TLV320AIC3262: Porting TLV320AIC3262 driver on TI Linux SDK 9.03

Part Number: TLV320AIC3262
Other Parts Discussed in Thread: AM5728, , TEST2

Tool/software:

Hi, 

I have a custom board based on am5728 SOC running TI linux SDK 9.03 and I want to port driver for TLV320AIC3262 device.

But I don't see any driver file for this device in sound/soc/codecs/ directory.

Please guide me with the steps needed.

-Vishal 

  • Hello Vishal,

    You  can find  all the available Linux drivers for different devices in this page. 

     https://e2e.ti.com/support/audio-group/audio/f/audio-forum/773056/faq-linux-drivers-device-drivers-for-aic31xx-dac31xx-aic325x-aic320x-aic326x-aic321x 

    Regards,

    Arash

  • Hi  ,

    I downloaded the tlv320aic326x.c and tlv320aic326x.h from the link you mentioned.

    I also downloaded the dependent .c / .h files as below (from the same source tree link). 

    include/linux/mfd/tlv320aic3262-registers.h
    include/linux/mfd/tlv320aic3xxx-core.h
    sound/soc/codecs/aic3xxx/
    


    I am getting so many compilation errors when compiling with 9.03 SDK as shown below.

    make -j4
      CALL    scripts/checksyscalls.sh
      CC [M]  sound/soc/codecs/tlv320aic326x.o
      CC      sound/soc/soc-ops.o
      CC      sound/soc/soc-link.o
      CC      sound/soc/soc-card.o
    sound/soc/codecs/tlv320aic326x.c:212:10: error: 'struct snd_soc_dai_ops' has no member named 'digital_mute'
      212 |         .digital_mute = aic3262_mute,
          |          ^~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:212:25: error: initialization of 'int (*)(struct snd_pcm_substream *, struct snd_soc_dai *)' from incompatible pointer type 'int (*)(struct snd_soc_dai *, int)' [-Werror=incompatible-pointer-types]
      212 |         .digital_mute = aic3262_mute,
          |                         ^~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:212:25: note: (near initialization for 'aic3262_asi1_dai_ops.hw_free')
    sound/soc/codecs/tlv320aic326x.c:219:10: error: 'struct snd_soc_dai_ops' has no member named 'digital_mute'
      219 |         .digital_mute = aic3262_mute,
          |          ^~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:219:25: error: initialization of 'int (*)(struct snd_pcm_substream *, struct snd_soc_dai *)' from incompatible pointer type 'int (*)(struct snd_soc_dai *, int)' [-Werror=incompatible-pointer-types]
      219 |         .digital_mute = aic3262_mute,
          |                         ^~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:219:25: note: (near initialization for 'aic3262_asi2_dai_ops.hw_free')
    sound/soc/codecs/tlv320aic326x.c:226:10: error: 'struct snd_soc_dai_ops' has no member named 'digital_mute'
      226 |         .digital_mute = aic3262_mute,
          |          ^~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:226:25: error: initialization of 'int (*)(struct snd_pcm_substream *, struct snd_soc_dai *)' from incompatible pointer type 'int (*)(struct snd_soc_dai *, int)' [-Werror=incompatible-pointer-types]
      226 |         .digital_mute = aic3262_mute,
          |                         ^~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:226:25: note: (near initialization for 'aic3262_asi3_dai_ops.hw_free')
    sound/soc/codecs/tlv320aic326x.c: In function 'aic326x_hp_event':
    sound/soc/codecs/tlv320aic326x.c:647:39: error: implicit declaration of function 'snd_soc_dapm_to_codec'; did you mean 'snd_soc_dapm_to_component'? [-Werror=implicit-function-declaration]
      647 |         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
          |                                       ^~~~~~~~~~~~~~~~~~~~~
          |                                       snd_soc_dapm_to_component
    sound/soc/codecs/tlv320aic326x.c:647:39: warning: initialization of 'struct snd_soc_codec *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    sound/soc/codecs/tlv320aic326x.c:663:25: error: implicit declaration of function 'snd_soc_update_bits'; did you mean 'snd_ac97_update_bits'? [-Werror=implicit-function-declaration]
      663 |                         snd_soc_update_bits(codec, AIC3262_CHARGE_PUMP_CNTL,
          |                         ^~~~~~~~~~~~~~~~~~~
          |                         snd_ac97_update_bits
    sound/soc/codecs/tlv320aic326x.c:666:25: error: implicit declaration of function 'snd_soc_write'; did you mean 'snd_ac97_write'? [-Werror=implicit-function-declaration]
      666 |                         snd_soc_write(codec, mute_reg, 0x80);
          |                         ^~~~~~~~~~~~~
          |                         snd_ac97_write
    sound/soc/codecs/tlv320aic326x.c:673:52: error: invalid use of undefined type 'struct snd_soc_codec'
      673 |                 ret_wbits = aic3xxx_wait_bits(codec->control_data,
          |                                                    ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:678:38: error: invalid use of undefined type 'struct snd_soc_codec'
      678 |                         dev_err(codec->dev, "HP POST_PMU timedout\n");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:678:25: note: in expansion of macro 'dev_err'
      678 |                         dev_err(codec->dev, "HP POST_PMU timedout\n");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:690:27: error: implicit declaration of function 'snd_soc_read'; did you mean 'snd_soc_cnew'? [-Werror=implicit-function-declaration]
      690 |                 hpl_hpr = snd_soc_read(codec, AIC3262_HP_AMP_CNTL_R1);
          |                           ^~~~~~~~~~~~
          |                           snd_soc_cnew
    sound/soc/codecs/tlv320aic326x.c:701:52: error: invalid use of undefined type 'struct snd_soc_codec'
      701 |                 ret_wbits = aic3xxx_wait_bits(codec->control_data,
          |                                                    ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:706:38: error: invalid use of undefined type 'struct snd_soc_codec'
      706 |                         dev_err(codec->dev, "HP POST_PMD timedout\n");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:706:25: note: in expansion of macro 'dev_err'
      706 |                         dev_err(codec->dev, "HP POST_PMD timedout\n");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic326x_dac_event':
    sound/soc/codecs/tlv320aic326x.c:732:39: warning: initialization of 'struct snd_soc_codec *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
      732 |         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
          |                                       ^~~~~~~~~~~~~~~~~~~~~
      CC      sound/soc/soc-generic-dmaengine-pcm.o
      CC      sound/soc/soc-ac97.o
    sound/soc/codecs/tlv320aic326x.c:736:40: error: implicit declaration of function 'snd_soc_codec_get_drvdata'; did you mean 'snd_soc_card_get_drvdata'? [-Werror=implicit-function-declaration]
      736 |         struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
          |                                        snd_soc_card_get_drvdata
    sound/soc/codecs/tlv320aic326x.c:736:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    sound/soc/codecs/tlv320aic326x.c:751:52: error: invalid use of undefined type 'struct snd_soc_codec'
      751 |                 ret_wbits = aic3xxx_wait_bits(codec->control_data,
          |                                                    ^~
    sound/soc/codecs/tlv320aic326x.c:756:53: error: invalid use of undefined type 'struct snd_soc_codec'
      756 |                 sync_needed = aic3xxx_reg_read(codec->control_data,
          |                                                     ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:770:38: error: invalid use of undefined type 'struct snd_soc_codec'
      770 |                         dev_err(codec->dev, "DAC POST_PMU timedout\n");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:770:25: note: in expansion of macro 'dev_err'
      770 |                         dev_err(codec->dev, "DAC POST_PMU timedout\n");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:776:52: error: invalid use of undefined type 'struct snd_soc_codec'
      776 |                 ret_wbits = aic3xxx_wait_bits(codec->control_data,
          |                                                    ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:784:38: error: invalid use of undefined type 'struct snd_soc_codec'
      784 |                         dev_err(codec->dev, "DAC POST_PMD timedout\n");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:784:25: note: in expansion of macro 'dev_err'
      784 |                         dev_err(codec->dev, "DAC POST_PMD timedout\n");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_set_mode_get':
    sound/soc/codecs/tlv320aic326x.c:854:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
      854 |         struct aic3262_priv *priv_ds = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_set_mode_put':
    sound/soc/codecs/tlv320aic326x.c:873:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
      873 |         struct aic3262_priv *priv_ds = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:881:30: error: invalid use of undefined type 'struct snd_soc_codec'
      881 |                 dev_err(codec->dev, "failed to load firmware\n");
          |                              ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:881:17: note: in expansion of macro 'dev_err'
      881 |                 dev_err(codec->dev, "failed to load firmware\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic326x_adc_dsp_event':
    sound/soc/codecs/tlv320aic326x.c:899:39: warning: initialization of 'struct snd_soc_codec *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
      899 |         struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
          |                                       ^~~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:904:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
      904 |         struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:918:52: error: invalid use of undefined type 'struct snd_soc_codec'
      918 |                 ret_wbits = aic3xxx_wait_bits(codec->control_data,
          |                                                    ^~
    sound/soc/codecs/tlv320aic326x.c:922:54: error: invalid use of undefined type 'struct snd_soc_codec'
      922 |                 sync_needed =  aic3xxx_reg_read(codec->control_data,
          |                                                      ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:934:38: error: invalid use of undefined type 'struct snd_soc_codec'
      934 |                         dev_err(codec->dev, "ADC POST_PMU timedout\n");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:934:25: note: in expansion of macro 'dev_err'
      934 |                         dev_err(codec->dev, "ADC POST_PMU timedout\n");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:939:52: error: invalid use of undefined type 'struct snd_soc_codec'
      939 |                 ret_wbits = aic3xxx_wait_bits(codec->control_data,
          |                                                    ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:946:38: error: invalid use of undefined type 'struct snd_soc_codec'
      946 |                         dev_err(codec->dev, "ADC POST_PMD timedout\n");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:946:25: note: in expansion of macro 'dev_err'
      946 |                         dev_err(codec->dev, "ADC POST_PMD timedout\n");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_firmware_load':
    sound/soc/codecs/tlv320aic326x.c:1495:43: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     1495 |         struct aic3262_priv *private_ds = snd_soc_codec_get_drvdata(codec);
          |                                           ^~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:1504:30: error: invalid use of undefined type 'struct snd_soc_codec'
     1504 |                 dev_dbg(codec->dev, "Firmware binary load\n");
          |                              ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:1504:17: note: in expansion of macro 'dev_dbg'
     1504 |                 dev_dbg(codec->dev, "Firmware binary load\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:1509:38: error: invalid use of undefined type 'struct snd_soc_codec'
     1509 |                         dev_err(codec->dev, "Firmware binary load failed\n");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:1509:25: note: in expansion of macro 'dev_err'
     1509 |                         dev_err(codec->dev, "Firmware binary load failed\n");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:1519:30: error: invalid use of undefined type 'struct snd_soc_codec'
     1519 |                 dev_err(codec->dev, "request_firmware failed\n");
          |                              ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:1519:17: note: in expansion of macro 'dev_err'
     1519 |                 dev_err(codec->dev, "request_firmware failed\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_hs_jack_report':
    sound/soc/codecs/tlv320aic326x.c:1560:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     1560 |         struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_hs_jack_detect':
    sound/soc/codecs/tlv320aic326x.c:1598:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     1598 |         struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_audio_handler':
    sound/soc/codecs/tlv320aic326x.c:1633:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     1633 |         struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_reg_read':
    sound/soc/codecs/tlv320aic326x.c:1660:38: error: invalid use of undefined type 'struct snd_soc_codec'
     1660 |         return aic3xxx_reg_read(codec->control_data, aic3262_ops_cfw2reg(reg));
          |                                      ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_reg_write':
    sound/soc/codecs/tlv320aic326x.c:1666:39: error: invalid use of undefined type 'struct snd_soc_codec'
     1666 |         return aic3xxx_reg_write(codec->control_data,
          |                                       ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_set_bits':
    sound/soc/codecs/tlv320aic326x.c:1673:38: error: invalid use of undefined type 'struct snd_soc_codec'
     1673 |         return aic3xxx_set_bits(codec->control_data,
          |                                      ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_bulk_read':
    sound/soc/codecs/tlv320aic326x.c:1681:39: error: invalid use of undefined type 'struct snd_soc_codec'
     1681 |         return aic3xxx_bulk_read(codec->control_data,
          |                                       ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_bulk_write':
    sound/soc/codecs/tlv320aic326x.c:1688:40: error: invalid use of undefined type 'struct snd_soc_codec'
     1688 |         return aic3xxx_bulk_write(codec->control_data,
          |                                        ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_lock':
    sound/soc/codecs/tlv320aic326x.c:1712:26: error: invalid use of undefined type 'struct snd_soc_codec'
     1712 |         mutex_lock(&codec->component.io_mutex);
          |                          ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_unlock':
    sound/soc/codecs/tlv320aic326x.c:1728:28: error: invalid use of undefined type 'struct snd_soc_codec'
     1728 |         mutex_unlock(&codec->component.io_mutex);
          |                            ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_stop':
    sound/soc/codecs/tlv320aic326x.c:1755:39: error: invalid use of undefined type 'struct snd_soc_codec'
     1755 |                 aic3xxx_set_bits(codec->control_data,
          |                                       ^~
    sound/soc/codecs/tlv320aic326x.c:1759:39: error: invalid use of undefined type 'struct snd_soc_codec'
     1759 |                 aic3xxx_set_bits(codec->control_data,
          |                                       ^~
    sound/soc/codecs/tlv320aic326x.c:1763:41: error: invalid use of undefined type 'struct snd_soc_codec'
     1763 |                 !aic3xxx_wait_bits(codec->control_data,
          |                                         ^~
    sound/soc/codecs/tlv320aic326x.c:1770:41: error: invalid use of undefined type 'struct snd_soc_codec'
     1770 |                 !aic3xxx_wait_bits(codec->control_data,
          |                                         ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:1778:22: error: invalid use of undefined type 'struct snd_soc_codec'
     1778 |         dev_err(codec->dev, "Unable to turn off ADCs or DACs at [%s:%d]",
          |                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:1778:9: note: in expansion of macro 'dev_err'
     1778 |         dev_err(codec->dev, "Unable to turn off ADCs or DACs at [%s:%d]",
          |         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_restore':
    sound/soc/codecs/tlv320aic326x.c:1796:44: error: invalid use of undefined type 'struct snd_soc_codec'
     1796 |         sync_state = aic3xxx_reg_read(codec->control_data, AIC3262_DAC_PRB);
          |                                            ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_adaptivebuffer_swap':
    sound/soc/codecs/tlv320aic326x.c:1827:47: error: invalid use of undefined type 'struct snd_soc_codec'
     1827 |                         aic3xxx_set_bits(codec->control_data, sbuf[i][1],
          |                                               ^~
    sound/soc/codecs/tlv320aic326x.c:1829:53: error: invalid use of undefined type 'struct snd_soc_codec'
     1829 |                         if (!aic3xxx_wait_bits(codec->control_data,
          |                                                     ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:1831:38: error: invalid use of undefined type 'struct snd_soc_codec'
     1831 |                         dev_err(codec->dev, "miniDSP buffer swap failure");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:1831:25: note: in expansion of macro 'dev_err'
     1831 |                         dev_err(codec->dev, "miniDSP buffer swap failure");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_get_runstate':
    sound/soc/codecs/tlv320aic326x.c:1849:37: error: invalid use of undefined type 'struct snd_soc_codec'
     1849 |         dac = aic3xxx_reg_read(codec->control_data, AIC3262_DAC_FLAG);
          |                                     ^~
    sound/soc/codecs/tlv320aic326x.c:1850:37: error: invalid use of undefined type 'struct snd_soc_codec'
     1850 |         adc = aic3xxx_reg_read(codec->control_data, AIC3262_ADC_FLAG);
          |                                     ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_dsp_pwrdwn_status':
    sound/soc/codecs/tlv320aic326x.c:1867:31: error: invalid use of undefined type 'struct snd_soc_codec'
     1867 |         aic3xxx_set_bits(codec->control_data,
          |                               ^~
    sound/soc/codecs/tlv320aic326x.c:1869:31: error: invalid use of undefined type 'struct snd_soc_codec'
     1869 |         aic3xxx_set_bits(codec->control_data,
          |                               ^~
    sound/soc/codecs/tlv320aic326x.c:1872:37: error: invalid use of undefined type 'struct snd_soc_codec'
     1872 |         if (!aic3xxx_wait_bits(codec->control_data, AIC3262_ADC_FLAG,
          |                                     ^~
    sound/soc/codecs/tlv320aic326x.c:1876:37: error: invalid use of undefined type 'struct snd_soc_codec'
     1876 |         if (!aic3xxx_wait_bits(codec->control_data, AIC3262_DAC_FLAG,
          |                                     ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:1883:22: error: invalid use of undefined type 'struct snd_soc_codec'
     1883 |         dev_err(codec->dev, "DAC/ADC Power down timedout at [%s:%d]",
          |                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:1883:9: note: in expansion of macro 'dev_err'
     1883 |         dev_err(codec->dev, "DAC/ADC Power down timedout at [%s:%d]",
          |         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_dsp_pwrup':
    sound/soc/codecs/tlv320aic326x.c:1905:39: error: invalid use of undefined type 'struct snd_soc_codec'
     1905 |                 aic3xxx_set_bits(codec->control_data,
          |                                       ^~
    sound/soc/codecs/tlv320aic326x.c:1919:39: error: invalid use of undefined type 'struct snd_soc_codec'
     1919 |                 aic3xxx_set_bits(codec->control_data,
          |                                       ^~
    sound/soc/codecs/tlv320aic326x.c:1924:52: error: invalid use of undefined type 'struct snd_soc_codec'
     1924 |                 ret_wbits = aic3xxx_wait_bits(codec->control_data,
          |                                                    ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:1929:38: error: invalid use of undefined type 'struct snd_soc_codec'
     1929 |                         dev_err(codec->dev, "ADC Power down timedout\n");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:1929:25: note: in expansion of macro 'dev_err'
     1929 |                         dev_err(codec->dev, "ADC Power down timedout\n");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:1933:52: error: invalid use of undefined type 'struct snd_soc_codec'
     1933 |                 ret_wbits = aic3xxx_wait_bits(codec->control_data,
          |                                                    ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:1938:38: error: invalid use of undefined type 'struct snd_soc_codec'
     1938 |                         dev_err(codec->dev, "ADC Power down timedout\n");
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:1938:25: note: in expansion of macro 'dev_err'
     1938 |                         dev_err(codec->dev, "ADC Power down timedout\n");
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_codec_read':
    sound/soc/codecs/tlv320aic326x.c:1980:39: error: invalid use of undefined type 'struct snd_soc_codec'
     1980 |         value = aic3xxx_reg_read(codec->control_data, reg);
          |                                       ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:1981:22: error: invalid use of undefined type 'struct snd_soc_codec'
     1981 |         dev_dbg(codec->dev, "p %d , r 30 %x %x\n",
          |                      ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:1981:9: note: in expansion of macro 'dev_dbg'
     1981 |         dev_dbg(codec->dev, "p %d , r 30 %x %x\n",
          |         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_codec_write':
    sound/soc/codecs/tlv320aic326x.c:1999:22: error: invalid use of undefined type 'struct snd_soc_codec'
     1999 |         dev_dbg(codec->dev, "p %d, w 30 %x %x\n",
          |                      ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:1999:9: note: in expansion of macro 'dev_dbg'
     1999 |         dev_dbg(codec->dev, "p %d, w 30 %x %x\n",
          |         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2002:39: error: invalid use of undefined type 'struct snd_soc_codec'
     2002 |         return aic3xxx_reg_write(codec->control_data, reg, value);
          |                                       ^~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_set_interface_fmt':
    sound/soc/codecs/tlv320aic326x.c:2018:42: error: 'struct snd_soc_dai' has no member named 'codec'
     2018 |         struct snd_soc_codec *codec = dai->codec;
          |                                          ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:2061:30: error: invalid use of undefined type 'struct snd_soc_codec'
     2061 |                 dev_err(codec->dev, "Invalid DAI interface format\n");
          |                              ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:2061:17: note: in expansion of macro 'dev_err'
     2061 |                 dev_err(codec->dev, "Invalid DAI interface format\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_hw_params':
    sound/soc/codecs/tlv320aic326x.c:2088:42: error: 'struct snd_soc_pcm_runtime' has no member named 'codec'
     2088 |         struct snd_soc_codec *codec = rtd->codec;
          |                                          ^~
    sound/soc/codecs/tlv320aic326x.c:2089:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     2089 |         struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:2169:30: error: invalid use of undefined type 'struct snd_soc_codec'
     2169 |                 dev_err(codec->dev, "failed to set hardware params for AIC3262\n");
          |                              ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:2169:17: note: in expansion of macro 'dev_err'
     2169 |                 dev_err(codec->dev, "failed to set hardware params for AIC3262\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_mute':
    sound/soc/codecs/tlv320aic326x.c:2185:42: error: 'struct snd_soc_dai' has no member named 'codec'
     2185 |         struct snd_soc_codec *codec = dai->codec;
          |                                          ^~
    sound/soc/codecs/tlv320aic326x.c:2186:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     2186 |         struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:2188:22: error: invalid use of undefined type 'struct snd_soc_codec'
     2188 |         dev_dbg(codec->dev, "codec : %s : started\n", __func__);
          |                      ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:2188:9: note: in expansion of macro 'dev_dbg'
     2188 |         dev_dbg(codec->dev, "codec : %s : started\n", __func__);
          |         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2210:22: error: invalid use of undefined type 'struct snd_soc_codec'
     2210 |         dev_dbg(codec->dev, "codec : %s : ended\n", __func__);
          |                      ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:2210:9: note: in expansion of macro 'dev_dbg'
     2210 |         dev_dbg(codec->dev, "codec : %s : ended\n", __func__);
          |         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_set_dai_fmt':
    sound/soc/codecs/tlv320aic326x.c:2228:26: error: 'struct snd_soc_dai' has no member named 'codec'
     2228 |         codec = codec_dai->codec;
          |                          ^~
    sound/soc/codecs/tlv320aic326x.c:2229:17: warning: assignment to 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     2229 |         aic3262 = snd_soc_codec_get_drvdata(codec);
          |                 ^
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:2267:30: error: invalid use of undefined type 'struct snd_soc_codec'
     2267 |                 dev_err(codec->dev, "Invalid DAI master/slave" " interface\n");
          |                              ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:2267:17: note: in expansion of macro 'dev_err'
     2267 |                 dev_err(codec->dev, "Invalid DAI master/slave" " interface\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_dai_set_pll':
    sound/soc/codecs/tlv320aic326x.c:2318:42: error: 'struct snd_soc_dai' has no member named 'codec'
     2318 |         struct snd_soc_codec *codec = dai->codec;
          |                                          ^~
    sound/soc/codecs/tlv320aic326x.c:2319:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     2319 |         struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:2321:22: error: invalid use of undefined type 'struct snd_soc_codec'
     2321 |         dev_dbg(codec->dev, "In aic3262: dai_set_pll\n");
          |                      ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:2321:9: note: in expansion of macro 'dev_dbg'
     2321 |         dev_dbg(codec->dev, "In aic3262: dai_set_pll\n");
          |         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2322:22: error: invalid use of undefined type 'struct snd_soc_codec'
     2322 |         dev_dbg(codec->dev, "%d, %s, dai->id = %d\n", __LINE__,
          |                      ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:2322:9: note: in expansion of macro 'dev_dbg'
     2322 |         dev_dbg(codec->dev, "%d, %s, dai->id = %d\n", __LINE__,
          |         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_set_bias_level':
    sound/soc/codecs/tlv320aic326x.c:2352:30: error: invalid use of undefined type 'struct snd_soc_codec'
     2352 |                 dev_dbg(codec->dev, "set_bias_on\n");
          |                              ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:2352:17: note: in expansion of macro 'dev_dbg'
     2352 |                 dev_dbg(codec->dev, "set_bias_on\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2357:30: error: invalid use of undefined type 'struct snd_soc_codec'
     2357 |                 dev_dbg(codec->dev, "set_bias_prepare\n");
          |                              ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:2357:17: note: in expansion of macro 'dev_dbg'
     2357 |                 dev_dbg(codec->dev, "set_bias_prepare\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2366:30: error: invalid use of undefined type 'struct snd_soc_codec'
     2366 |                 dev_dbg(codec->dev, "set_bias_stby\n");
          |                              ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:2366:17: note: in expansion of macro 'dev_dbg'
     2366 |                 dev_dbg(codec->dev, "set_bias_stby\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2367:26: error: invalid use of undefined type 'struct snd_soc_codec'
     2367 |                 if (codec->component.dapm.bias_level == SND_SOC_BIAS_OFF) {
          |                          ^~
    sound/soc/codecs/tlv320aic326x.c:2368:50: error: invalid use of undefined type 'struct snd_soc_codec'
     2368 |                         pm_runtime_get_sync(codec->dev);
          |                                                  ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:2386:30: error: invalid use of undefined type 'struct snd_soc_codec'
     2386 |                 dev_dbg(codec->dev, "set_bias_off\n");
          |                              ^~
    ./include/linux/dev_printk.h:139:44: note: in definition of macro 'dev_no_printk'
      139 |                         _dev_printk(level, dev, fmt, ##__VA_ARGS__);    \
          |                                            ^~~
    sound/soc/codecs/tlv320aic326x.c:2386:17: note: in expansion of macro 'dev_dbg'
     2386 |                 dev_dbg(codec->dev, "set_bias_off\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2388:26: error: invalid use of undefined type 'struct snd_soc_codec'
     2388 |                 if (codec->component.dapm.bias_level == SND_SOC_BIAS_STANDBY) {
          |                          ^~
    sound/soc/codecs/tlv320aic326x.c:2396:45: error: invalid use of undefined type 'struct snd_soc_codec'
     2396 |                         pm_runtime_put(codec->dev);
          |                                             ^~
    sound/soc/codecs/tlv320aic326x.c:2401:14: error: invalid use of undefined type 'struct snd_soc_codec'
     2401 |         codec->component.dapm.bias_level = level;
          |              ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_codec_probe':
    sound/soc/codecs/tlv320aic326x.c:2445:30: error: invalid use of undefined type 'struct snd_soc_codec'
     2445 |                 dev_err(codec->dev, "codec pointer is NULL.\n");
          |                              ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:2445:17: note: in expansion of macro 'dev_err'
     2445 |                 dev_err(codec->dev, "codec pointer is NULL.\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2447:14: error: invalid use of undefined type 'struct snd_soc_codec'
     2447 |         codec->control_data = dev_get_drvdata(codec->dev->parent);
          |              ^~
    sound/soc/codecs/tlv320aic326x.c:2447:52: error: invalid use of undefined type 'struct snd_soc_codec'
     2447 |         codec->control_data = dev_get_drvdata(codec->dev->parent);
          |                                                    ^~
    sound/soc/codecs/tlv320aic326x.c:2448:24: error: invalid use of undefined type 'struct snd_soc_codec'
     2448 |         control = codec->control_data;
          |                        ^~
    sound/soc/codecs/tlv320aic326x.c:2453:9: error: implicit declaration of function 'snd_soc_codec_set_drvdata'; did you mean 'snd_soc_card_set_drvdata'? [-Werror=implicit-function-declaration]
     2453 |         snd_soc_codec_set_drvdata(codec, aic3262);
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~
          |         snd_soc_card_set_drvdata
    sound/soc/codecs/tlv320aic326x.c:2454:48: error: invalid use of undefined type 'struct snd_soc_codec'
     2454 |         aic3262->pdata = dev_get_platdata(codec->dev->parent);
          |                                                ^~
    In file included from ./include/linux/seqlock.h:19,
                     from ./include/linux/mm_types.h:20,
                     from ./include/linux/buildid.h:5,
                     from ./include/linux/module.h:14,
                     from sound/soc/codecs/tlv320aic326x.c:34:
    sound/soc/codecs/tlv320aic326x.c:2467:26: error: invalid use of undefined type 'struct snd_soc_codec'
     2467 |         mutex_init(&codec->component.io_mutex);
          |                          ^~
    ./include/linux/mutex.h:108:23: note: in definition of macro 'mutex_init'
      108 |         __mutex_init((mutex), #mutex, &__key);                          \
          |                       ^~~~~
    sound/soc/codecs/tlv320aic326x.c:2469:32: error: invalid use of undefined type 'struct snd_soc_codec'
     2469 |         pm_runtime_enable(codec->dev);
          |                                ^~
    sound/soc/codecs/tlv320aic326x.c:2470:32: error: invalid use of undefined type 'struct snd_soc_codec'
     2470 |         pm_runtime_resume(codec->dev);
          |                                ^~
    sound/soc/codecs/tlv320aic326x.c:2474:48: error: invalid use of undefined type 'struct snd_soc_codec'
     2474 |                 ret = aic3xxx_request_irq(codec->control_data,
          |                                                ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:2481:38: error: invalid use of undefined type 'struct snd_soc_codec'
     2481 |                         dev_err(codec->dev,
          |                                      ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:2481:25: note: in expansion of macro 'dev_err'
     2481 |                         dev_err(codec->dev,
          |                         ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2509:52: error: 'FW_ACTION_HOTPLUG' undeclared (first use in this function)
     2509 |         ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
          |                                                    ^~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2509:52: note: each undeclared identifier is reported only once for each function it appears in
    sound/soc/codecs/tlv320aic326x.c:2510:65: error: invalid use of undefined type 'struct snd_soc_codec'
     2510 |                                 "tlv320aic3262_fw_v1.bin", codec->dev,
          |                                                                 ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:2513:30: error: invalid use of undefined type 'struct snd_soc_codec'
     2513 |                 dev_err(codec->dev, "Firmware request failed\n");
          |                              ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:2513:17: note: in expansion of macro 'dev_err'
     2513 |                 dev_err(codec->dev, "Firmware request failed\n");
          |                 ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_codec_remove':
    sound/soc/codecs/tlv320aic326x.c:2537:40: warning: initialization of 'struct aic3262_priv *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
     2537 |         struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2538:40: error: invalid use of undefined type 'struct snd_soc_codec'
     2538 |         struct aic3xxx *control = codec->control_data;
          |                                        ^~
    In file included from ./include/linux/device.h:15,
                     from ./include/linux/acpi.h:15,
                     from ./include/linux/i2c.h:13,
                     from sound/soc/codecs/tlv320aic326x.c:39:
    sound/soc/codecs/tlv320aic326x.c:2550:31: error: invalid use of undefined type 'struct snd_soc_codec'
     2550 |                 dev_info(codec->dev, "Coded is not TLV320AIC3262\n");
          |                               ^~
    ./include/linux/dev_printk.h:110:25: note: in definition of macro 'dev_printk_index_wrap'
      110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
          |                         ^~~
    sound/soc/codecs/tlv320aic326x.c:2550:17: note: in expansion of macro 'dev_info'
     2550 |                 dev_info(codec->dev, "Coded is not TLV320AIC3262\n");
          |                 ^~~~~~~~
    sound/soc/codecs/tlv320aic326x.c: At top level:
    sound/soc/codecs/tlv320aic326x.c:2563:15: error: variable 'soc_codec_driver_aic326x' has initializer but incomplete type
     2563 | static struct snd_soc_codec_driver soc_codec_driver_aic326x = {
          |               ^~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2564:10: error: 'struct snd_soc_codec_driver' has no member named 'probe'
     2564 |         .probe = aic3262_codec_probe,
          |          ^~~~~
    sound/soc/codecs/tlv320aic326x.c:2564:18: warning: excess elements in struct initializer
     2564 |         .probe = aic3262_codec_probe,
          |                  ^~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2564:18: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2565:10: error: 'struct snd_soc_codec_driver' has no member named 'remove'
     2565 |         .remove = aic3262_codec_remove,
          |          ^~~~~~
    sound/soc/codecs/tlv320aic326x.c:2565:19: warning: excess elements in struct initializer
     2565 |         .remove = aic3262_codec_remove,
          |                   ^~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2565:19: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2566:10: error: 'struct snd_soc_codec_driver' has no member named 'suspend'
     2566 |         .suspend = aic3262_suspend,
          |          ^~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2566:20: warning: excess elements in struct initializer
     2566 |         .suspend = aic3262_suspend,
          |                    ^~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2566:20: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2567:10: error: 'struct snd_soc_codec_driver' has no member named 'resume'
     2567 |         .resume = aic3262_resume,
          |          ^~~~~~
    sound/soc/codecs/tlv320aic326x.c:2567:19: warning: excess elements in struct initializer
     2567 |         .resume = aic3262_resume,
          |                   ^~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2567:19: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2568:10: error: 'struct snd_soc_codec_driver' has no member named 'read'
     2568 |         .read = aic3262_codec_read,
          |          ^~~~
    sound/soc/codecs/tlv320aic326x.c:2568:17: warning: excess elements in struct initializer
     2568 |         .read = aic3262_codec_read,
          |                 ^~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2568:17: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2569:10: error: 'struct snd_soc_codec_driver' has no member named 'write'
     2569 |         .write = aic3262_codec_write,
          |          ^~~~~
    sound/soc/codecs/tlv320aic326x.c:2569:18: warning: excess elements in struct initializer
     2569 |         .write = aic3262_codec_write,
          |                  ^~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2569:18: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2570:10: error: 'struct snd_soc_codec_driver' has no member named 'controls'
     2570 |         .controls = aic3262_snd_controls,
          |          ^~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2570:21: warning: excess elements in struct initializer
     2570 |         .controls = aic3262_snd_controls,
          |                     ^~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2570:21: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2571:10: error: 'struct snd_soc_codec_driver' has no member named 'num_controls'
     2571 |         .num_controls = ARRAY_SIZE(aic3262_snd_controls),
          |          ^~~~~~~~~~~~
    In file included from ./include/linux/cpumask.h:10,
                     from ./include/linux/mm_types_task.h:14,
                     from ./include/linux/mm_types.h:5,
                     from ./include/linux/buildid.h:5,
                     from ./include/linux/module.h:14,
                     from sound/soc/codecs/tlv320aic326x.c:34:
    ./include/linux/kernel.h:55:25: warning: excess elements in struct initializer
       55 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
          |                         ^
    sound/soc/codecs/tlv320aic326x.c:2571:25: note: in expansion of macro 'ARRAY_SIZE'
     2571 |         .num_controls = ARRAY_SIZE(aic3262_snd_controls),
          |                         ^~~~~~~~~~
    ./include/linux/kernel.h:55:25: note: (near initialization for 'soc_codec_driver_aic326x')
       55 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
          |                         ^
    sound/soc/codecs/tlv320aic326x.c:2571:25: note: in expansion of macro 'ARRAY_SIZE'
     2571 |         .num_controls = ARRAY_SIZE(aic3262_snd_controls),
          |                         ^~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2572:10: error: 'struct snd_soc_codec_driver' has no member named 'dapm_widgets'
     2572 |         .dapm_widgets = aic3262_dapm_widgets,
          |          ^~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2572:25: warning: excess elements in struct initializer
     2572 |         .dapm_widgets = aic3262_dapm_widgets,
          |                         ^~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2572:25: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2573:10: error: 'struct snd_soc_codec_driver' has no member named 'num_dapm_widgets'
     2573 |         .num_dapm_widgets = ARRAY_SIZE(aic3262_dapm_widgets),
          |          ^~~~~~~~~~~~~~~~
    In file included from ./include/linux/cpumask.h:10,
                     from ./include/linux/mm_types_task.h:14,
                     from ./include/linux/mm_types.h:5,
                     from ./include/linux/buildid.h:5,
                     from ./include/linux/module.h:14,
                     from sound/soc/codecs/tlv320aic326x.c:34:
    ./include/linux/kernel.h:55:25: warning: excess elements in struct initializer
       55 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
          |                         ^
    sound/soc/codecs/tlv320aic326x.c:2573:29: note: in expansion of macro 'ARRAY_SIZE'
     2573 |         .num_dapm_widgets = ARRAY_SIZE(aic3262_dapm_widgets),
          |                             ^~~~~~~~~~
    ./include/linux/kernel.h:55:25: note: (near initialization for 'soc_codec_driver_aic326x')
       55 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
          |                         ^
    sound/soc/codecs/tlv320aic326x.c:2573:29: note: in expansion of macro 'ARRAY_SIZE'
     2573 |         .num_dapm_widgets = ARRAY_SIZE(aic3262_dapm_widgets),
          |                             ^~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2574:10: error: 'struct snd_soc_codec_driver' has no member named 'dapm_routes'
     2574 |         .dapm_routes = aic3262_dapm_routes,
          |          ^~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2574:24: warning: excess elements in struct initializer
     2574 |         .dapm_routes = aic3262_dapm_routes,
          |                        ^~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2574:24: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2575:10: error: 'struct snd_soc_codec_driver' has no member named 'num_dapm_routes'
     2575 |         .num_dapm_routes = ARRAY_SIZE(aic3262_dapm_routes),
          |          ^~~~~~~~~~~~~~~
    In file included from ./include/linux/cpumask.h:10,
                     from ./include/linux/mm_types_task.h:14,
                     from ./include/linux/mm_types.h:5,
                     from ./include/linux/buildid.h:5,
                     from ./include/linux/module.h:14,
                     from sound/soc/codecs/tlv320aic326x.c:34:
    ./include/linux/kernel.h:55:25: warning: excess elements in struct initializer
       55 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
          |                         ^
    sound/soc/codecs/tlv320aic326x.c:2575:28: note: in expansion of macro 'ARRAY_SIZE'
     2575 |         .num_dapm_routes = ARRAY_SIZE(aic3262_dapm_routes),
          |                            ^~~~~~~~~~
    ./include/linux/kernel.h:55:25: note: (near initialization for 'soc_codec_driver_aic326x')
       55 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
          |                         ^
    sound/soc/codecs/tlv320aic326x.c:2575:28: note: in expansion of macro 'ARRAY_SIZE'
     2575 |         .num_dapm_routes = ARRAY_SIZE(aic3262_dapm_routes),
          |                            ^~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2576:10: error: 'struct snd_soc_codec_driver' has no member named 'set_bias_level'
     2576 |         .set_bias_level = aic3262_set_bias_level,
          |          ^~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2576:27: warning: excess elements in struct initializer
     2576 |         .set_bias_level = aic3262_set_bias_level,
          |                           ^~~~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2576:27: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2577:10: error: 'struct snd_soc_codec_driver' has no member named 'reg_cache_size'
     2577 |         .reg_cache_size = 0,
          |          ^~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2577:27: warning: excess elements in struct initializer
     2577 |         .reg_cache_size = 0,
          |                           ^
    sound/soc/codecs/tlv320aic326x.c:2577:27: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2578:10: error: 'struct snd_soc_codec_driver' has no member named 'reg_word_size'
     2578 |         .reg_word_size = sizeof(u8),
          |          ^~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2578:26: warning: excess elements in struct initializer
     2578 |         .reg_word_size = sizeof(u8),
          |                          ^~~~~~
    sound/soc/codecs/tlv320aic326x.c:2578:26: note: (near initialization for 'soc_codec_driver_aic326x')
    sound/soc/codecs/tlv320aic326x.c:2579:10: error: 'struct snd_soc_codec_driver' has no member named 'reg_cache_default'
     2579 |         .reg_cache_default = NULL,
          |          ^~~~~~~~~~~~~~~~~
    In file included from ./include/uapi/linux/posix_types.h:5,
                     from ./include/uapi/linux/types.h:14,
                     from ./include/linux/types.h:6,
                     from ./include/linux/kasan-checks.h:5,
                     from ./include/asm-generic/rwonce.h:26,
                     from ./arch/arm/include/generated/asm/rwonce.h:1,
                     from ./include/linux/compiler.h:246,
                     from ./include/linux/build_bug.h:5,
                     from ./include/linux/container_of.h:5,
                     from ./include/linux/list.h:5,
                     from ./include/linux/module.h:12,
                     from sound/soc/codecs/tlv320aic326x.c:34:
    ./include/linux/stddef.h:8:14: warning: excess elements in struct initializer
        8 | #define NULL ((void *)0)
          |              ^
    sound/soc/codecs/tlv320aic326x.c:2579:30: note: in expansion of macro 'NULL'
     2579 |         .reg_cache_default = NULL,
          |                              ^~~~
    ./include/linux/stddef.h:8:14: note: (near initialization for 'soc_codec_driver_aic326x')
        8 | #define NULL ((void *)0)
          |              ^
    sound/soc/codecs/tlv320aic326x.c:2579:30: note: in expansion of macro 'NULL'
     2579 |         .reg_cache_default = NULL,
          |                              ^~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic326x_probe':
    sound/soc/codecs/tlv320aic326x.c:2584:16: error: implicit declaration of function 'snd_soc_register_codec'; did you mean 'snd_soc_register_dai'? [-Werror=implicit-function-declaration]
     2584 |         return snd_soc_register_codec(&pdev->dev, &soc_codec_driver_aic326x,
          |                ^~~~~~~~~~~~~~~~~~~~~~
          |                snd_soc_register_dai
    sound/soc/codecs/tlv320aic326x.c: In function 'aic326x_remove':
    sound/soc/codecs/tlv320aic326x.c:2592:9: error: implicit declaration of function 'snd_soc_unregister_codec'; did you mean 'snd_soc_unregister_dai'? [-Werror=implicit-function-declaration]
     2592 |         snd_soc_unregister_codec(&pdev->dev);
          |         ^~~~~~~~~~~~~~~~~~~~~~~~
          |         snd_soc_unregister_dai
    sound/soc/codecs/tlv320aic326x.c: At top level:
    sound/soc/codecs/tlv320aic326x.c:2563:36: error: storage size of 'soc_codec_driver_aic326x' isn't known
     2563 | static struct snd_soc_codec_driver soc_codec_driver_aic326x = {
          |                                    ^~~~~~~~~~~~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_set_interface_fmt':
    sound/soc/codecs/tlv320aic326x.c:2045:27: warning: this statement may fall through [-Wimplicit-fallthrough=]
     2045 |                 dsp_a_val = 0x1;        /* Intentionally falling through */
          |                 ~~~~~~~~~~^~~~~
    sound/soc/codecs/tlv320aic326x.c:2046:9: note: here
     2046 |         case SND_SOC_DAIFMT_DSP_B:
          |         ^~~~
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_codec_write':
    sound/soc/codecs/tlv320aic326x.c:2003:1: error: control reaches end of non-void function [-Werror=return-type]
     2003 | }
          | ^
    cc1: some warnings being treated as errors
    make[4]: *** [scripts/Makefile.build:250: sound/soc/codecs/tlv320aic326x.o] Error 1
    make[3]: *** [scripts/Makefile.build:505: sound/soc/codecs] Error 2
    make[3]: *** Waiting for unfinished jobs....
    make[2]: *** [scripts/Makefile.build:505: sound/soc] Error 2
    make[1]: *** [scripts/Makefile.build:505: sound] Error 2
    make: *** [Makefile:2009: .] Error 2
    

    Please help me resolve the issues!

    -Vishal

  • Hello Vishal, I asked one of our software experts, Raphael,  to take a look at this as I am not the right person to help furthur.

    Regards,

    Arash

  • Hello Arash,

    Could you please provide a response at the earliest? I’m unable to proceed due to this issue.

  •   

    I have created a patch addressing the compilation issues for kernel version 6.1 on RPI kernel (Build test only).

    Please check if this solves the issue on your build setup and let me know if you find any issues with the compilation steps. 

    Edit: patch v2

    From b82661789b96a0c33bca104fc6709f9ae93e2100 Mon Sep 17 00:00:00 2001
    From: Niranjan H Y <niranjan.hy@ti.com>
    Date: Mon, 1 Sep 2025 14:12:48 +0530
    Subject: [PATCH v2] add tlv320aic3262 driver
    
    ---
     drivers/mfd/Kconfig                         |   31 +
     drivers/mfd/Makefile                        |    2 +
     drivers/mfd/tlv320aic3xxx-core.c            |  570 ++++
     drivers/mfd/tlv320aic3xxx-i2c.c             |  142 +
     drivers/mfd/tlv320aic3xxx-irq.c             |  222 ++
     drivers/mfd/tlv320aic3xxx-spi.c             |   91 +
     include/linux/mfd/tlv320aic3262-registers.h |  342 +++
     include/linux/mfd/tlv320aic3xxx-core.h      |  291 ++
     sound/soc/codecs/Kconfig                    |    8 +
     sound/soc/codecs/Makefile                   |    2 +
     sound/soc/codecs/aic3xxx/aic3xxx_cfw.h      |  529 ++++
     sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c  | 1134 ++++++++
     sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h  |   95 +
     sound/soc/codecs/tlv320aic326x.c            | 2640 +++++++++++++++++++
     sound/soc/codecs/tlv320aic326x.h            |  134 +
     15 files changed, 6233 insertions(+)
     create mode 100644 drivers/mfd/tlv320aic3xxx-core.c
     create mode 100644 drivers/mfd/tlv320aic3xxx-i2c.c
     create mode 100644 drivers/mfd/tlv320aic3xxx-irq.c
     create mode 100644 drivers/mfd/tlv320aic3xxx-spi.c
     create mode 100644 include/linux/mfd/tlv320aic3262-registers.h
     create mode 100644 include/linux/mfd/tlv320aic3xxx-core.h
     create mode 100644 sound/soc/codecs/aic3xxx/aic3xxx_cfw.h
     create mode 100644 sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c
     create mode 100644 sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h
     create mode 100644 sound/soc/codecs/tlv320aic326x.c
     create mode 100644 sound/soc/codecs/tlv320aic326x.h
    
    diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
    index 6c18ff956..6f5cde259 100644
    --- a/drivers/mfd/Kconfig
    +++ b/drivers/mfd/Kconfig
    @@ -1208,6 +1208,37 @@ config MFD_RETU
     	  Retu and Tahvo are a multi-function devices found on Nokia
     	  Internet Tablets (770, N800 and N810).
     
    +config AIC3XXX_I2C_REGMAP
    +	bool "I2C regmap support for TI AIC3XXX codecs"
    +	select REGMAP_I2C
    +	default y
    +	help
    +	  Support for the Texas Instruments TLV320AIC3XXX family of audio SoC
    +	  core functionality controlled via I2C.
    +	  Please select individual components.
    +
    +config AIC3XXX_SPI_REGMAP
    +	bool "SPI regmap support for TI AIC3XXX codecs"
    +	select REGMAP_SPI
    +	default n
    +	help
    +	  Support for the Texas Instruments TLV320AIC3XXX family of audio SoC
    +	  core functionality controlled via SPI.
    +	  Please select individual components.
    +
    +config AIC3XXX_CORE
    +	bool "Support for AIC3XXX audio codec"
    +	#depends on GENERIC_HARDIRQS
    +	select MFD_CORE
    +	select AIC3XXX_SPI_REGMAP
    +	select AIC3XXX_I2C_REGMAP
    +	default n
    +	help
    +	  Say yes here if you want support for Texas Instruments AIC3XXX audio
    +	  codec. This driver provides common support for accessing the device,
    +	  additional drivers must be enabled in order to use the
    +	  functionality of the device (audio, vibra).
    +
     config MFD_PM8XXX
     	tristate "Qualcomm PM8xxx PMIC chips driver"
     	depends on ARM || HEXAGON || COMPILE_TEST
    diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
    index 05e09bf92..437a4ca3e 100644
    --- a/drivers/mfd/Makefile
    +++ b/drivers/mfd/Makefile
    @@ -32,6 +32,8 @@ obj-$(CONFIG_STMPE_I2C)		+= stmpe-i2c.o
     obj-$(CONFIG_STMPE_SPI)		+= stmpe-spi.o
     obj-$(CONFIG_MFD_SUN6I_PRCM)	+= sun6i-prcm.o
     obj-$(CONFIG_MFD_TC3589X)	+= tc3589x.o
    +tlv320aic3xxx-objs := tlv320aic3xxx-core.o tlv320aic3xxx-irq.o tlv320aic3xxx-i2c.o
    +obj-$(CONFIG_AIC3XXX_CORE)	+= tlv320aic3xxx.o
     obj-$(CONFIG_MFD_TQMX86)	+= tqmx86.o
     
     obj-$(CONFIG_MFD_LOCHNAGAR)	+= lochnagar-i2c.o
    diff --git a/drivers/mfd/tlv320aic3xxx-core.c b/drivers/mfd/tlv320aic3xxx-core.c
    new file mode 100644
    index 000000000..943825455
    --- /dev/null
    +++ b/drivers/mfd/tlv320aic3xxx-core.c
    @@ -0,0 +1,570 @@
    +/*
    + * tlv320aic3xxx-core.c  -- driver for TLV320AIC3XXX
    + *
    + * Author:      Mukund Navada <navada@ti.com>
    + *              Mehar Bajwa <mehar.bajwa@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +#include <linux/kernel.h>
    +#include <linux/module.h>
    +#include <linux/slab.h>
    +#include <linux/i2c.h>
    +#include <linux/err.h>
    +#include <linux/delay.h>
    +#include <linux/regmap.h>
    +#include <linux/mfd/core.h>
    +#include <linux/pm_runtime.h>
    +#include <linux/regulator/consumer.h>
    +#include <linux/regulator/machine.h>
    +#include <linux/gpio.h>
    +
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +#include <linux/mfd/tlv320aic3262-registers.h>
    +
    +struct aic3262_gpio {
    +	unsigned int reg;
    +	u8 mask;
    +	u8 shift;
    +};
    +struct aic3262_gpio aic3262_gpio_control[] = {
    +	{
    +	 .reg = AIC3262_GPIO1_IO_CNTL,
    +	 .mask = AIC3262_GPIO_D6_D2,
    +	 .shift = AIC3262_GPIO_D2_SHIFT,
    +	 },
    +	{
    +	 .reg = AIC3262_GPIO2_IO_CNTL,
    +	 .mask = AIC3262_GPIO_D6_D2,
    +	 .shift = AIC3262_GPIO_D2_SHIFT,
    +	 },
    +	{
    +	 .reg = AIC3262_GPI1_EN,
    +	 .mask = AIC3262_GPI1_D2_D1,
    +	 .shift = AIC3262_GPIO_D1_SHIFT,
    +	 },
    +	{
    +	 .reg = AIC3262_GPI2_EN,
    +	 .mask = AIC3262_GPI2_D5_D4,
    +	 .shift = AIC3262_GPIO_D4_SHIFT,
    +	 },
    +	{
    +	 .reg = AIC3262_GPO1_OUT_CNTL,
    +	 .mask = AIC3262_GPO1_D4_D1,
    +	 .shift = AIC3262_GPIO_D1_SHIFT,
    +	 },
    +};
    +
    +static int set_aic3xxx_book(struct aic3xxx *aic3xxx, int book)
    +{
    +	int ret = 0;
    +	u8 page_buf[] = { 0x0, 0x0 };
    +	u8 book_buf[] = { 0x7f, 0x0 };
    +
    +	ret = regmap_write(aic3xxx->regmap, page_buf[0], page_buf[1]);
    +
    +	if (ret < 0)
    +		return ret;
    +	book_buf[1] = book;
    +	ret = regmap_write(aic3xxx->regmap, book_buf[0], book_buf[1]);
    +
    +	if (ret < 0)
    +		return ret;
    +	aic3xxx->book_no = book;
    +	aic3xxx->page_no = 0;
    +
    +	return ret;
    +}
    +
    +static int set_aic3xxx_page(struct aic3xxx *aic3xxx, int page)
    +{
    +	int ret = 0;
    +	u8 page_buf[] = { 0x0, 0x0 };
    +
    +	page_buf[1] = page;
    +	ret = regmap_write(aic3xxx->regmap, page_buf[0], page_buf[1]);
    +
    +	if (ret < 0)
    +		return ret;
    +	aic3xxx->page_no = page;
    +	return ret;
    +}
    +/**
    + * aic3xxx_reg_read: Read a single TLV320AIC3262 register.
    + *
    + * @aic3xxx: Device to read from.
    + * @reg: Register to read.
    + */
    +int aic3xxx_reg_read(struct aic3xxx *aic3xxx, unsigned int reg)
    +{
    +	unsigned int val;
    +	int ret;
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	u8 book, page, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (aic3xxx->book_no != book) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +
    +	if (aic3xxx->page_no != page) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_read(aic3xxx->regmap, offset, &val);
    +	mutex_unlock(&aic3xxx->io_lock);
    +
    +	if (ret < 0)
    +		return ret;
    +	else
    +		return val;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_reg_read);
    +
    +/**
    + * aic3xxx_bulk_read: Read multiple TLV320AIC3262 registers
    + *
    + * @aic3xxx: Device to read from
    + * @reg: First register
    + * @count: Number of registers
    + * @buf: Buffer to fill.  The data will be returned big endian.
    + */
    +int aic3xxx_bulk_read(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      int count, u8 *buf)
    +{
    +	int ret;
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	u8 book, page, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (aic3xxx->book_no != book) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +
    +	if (aic3xxx->page_no != page) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_bulk_read(aic3xxx->regmap, offset, buf, count);
    +	mutex_unlock(&aic3xxx->io_lock);
    +		return ret;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_bulk_read);
    +
    +/**
    + * aic3xxx_reg_write: Write a single TLV320AIC3262 register.
    + *
    + * @aic3xxx: Device to write to.
    + * @reg: Register to write to.
    + * @val: Value to write.
    + */
    +int aic3xxx_reg_write(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      unsigned char val)
    +{
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	int ret = 0;
    +	u8 page, book, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (book != aic3xxx->book_no) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	if (page != aic3xxx->page_no) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_write(aic3xxx->regmap, reg, val);
    +	mutex_unlock(&aic3xxx->io_lock);
    +	return ret;
    +
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_reg_write);
    +
    +/**
    + * aic3xxx_bulk_write: Write multiple TLV320AIC3262 registers
    + *
    + * @aic3xxx: Device to write to
    + * @reg: First register
    + * @count: Number of registers
    + * @buf: Buffer to write from.  Data must be big-endian formatted.
    + */
    +int aic3xxx_bulk_write(struct aic3xxx *aic3xxx, unsigned int reg,
    +		       int count, const u8 *buf)
    +{
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	int ret = 0;
    +	u8 page, book, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (book != aic3xxx->book_no) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	if (page != aic3xxx->page_no) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_raw_write(aic3xxx->regmap, reg, buf, count);
    +	mutex_unlock(&aic3xxx->io_lock);
    +	return ret;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_bulk_write);
    +
    +/**
    + * aic3xxx_set_bits: Set the value of a bitfield in a TLV320AIC3262 register
    + *
    + * @aic3xxx: Device to write to.
    + * @reg: Register to write to.
    + * @mask: Mask of bits to set.
    + * @val: Value to set (unshifted)
    + */
    +int aic3xxx_set_bits(struct aic3xxx *aic3xxx, unsigned int reg,
    +		     unsigned char mask, unsigned char val)
    +{
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	int ret = 0;
    +	u8 page, book, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (book != aic3xxx->book_no) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	if (page != aic3xxx->page_no) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_update_bits(aic3xxx->regmap, offset, mask, val);
    +	mutex_unlock(&aic3xxx->io_lock);
    +	return ret;
    +
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_set_bits);
    +
    +/**
    + * aic3xxx_wait_bits: wait for a value of a bitfield in a TLV320AIC3262 register
    + *
    + * @aic3xxx: Device to write to.
    + * @reg: Register to write to.
    + * @mask: Mask of bits to set.
    + * @val: Value to set (unshifted)
    + * @mdelay: mdelay value in each iteration in milliseconds
    + * @count: iteration count for timeout
    + */
    +int aic3xxx_wait_bits(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      unsigned char mask, unsigned char val, int sleep,
    +		      int counter)
    +{
    +	int status;
    +	int timeout = sleep * counter;
    +
    +	status = aic3xxx_reg_read(aic3xxx, reg);
    +	while (((status & mask) != val) && counter) {
    +		mdelay(sleep);
    +		status = aic3xxx_reg_read(aic3xxx, reg);
    +		counter--;
    +	};
    +	if (!counter)
    +		dev_err(aic3xxx->dev,
    +			"wait_bits timedout (%d millisecs). lastval 0x%x\n",
    +			timeout, status);
    +	return counter;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_wait_bits);
    +
    +static struct mfd_cell aic3262_devs[] = {
    +	{
    +	.name = "tlv320aic3262-codec",
    +	},
    +	//{
    +	//.name = "tlv320aic3262-gpio",
    +	//},
    +};
    +
    +static struct mfd_cell aic3285_devs[] = {
    +	{ .name = "tlv320aic3285-codec" },
    +	{ .name = "tlv320aic3285-extcon" },
    +	{ .name = "tlv320aic3285-gpio" },
    +};
    +
    +static int aic3xxx_parse_pdata_from_of(struct aic3xxx *aic3xxx)
    +{
    +	u32 gpio_reset;
    +	s32 ret;
    +	struct device *dev = aic3xxx->dev;
    +	struct aic3xxx_pdata *pdata = aic3xxx->pdata;
    +	struct device_node *np = dev->of_node;
    +
    +	pdata->gpio_reset = 0;
    +	/* disable interrupts */
    +	pdata->naudint_irq = 0;
    +	pdata->gpio_irq = 0;
    +	pdata->irq_base = 0;
    +
    +	if (np) {
    +		ret = of_property_read_u32(np, "ti,reset-gpio", &gpio_reset);
    +		if (ret)
    +			dev_err(aic3xxx->dev, "Unable to read reset-gpio property\n");
    +	} else {
    +		dev_info(dev, "No device tree node\n");
    +	}
    +
    +	return 0;
    +}
    +
    +/**
    + * Instantiate the generic non-control parts of the device.
    + */
    +int aic3xxx_device_init(struct aic3xxx *aic3xxx, int irq)
    +{
    +	struct aic3xxx_pdata *pdata; // = aic3xxx->dev->platform_data;
    +	const char *devname;
    +	int ret, i;
    +	u8 resetVal = 1;
    +
    +	dev_info(aic3xxx->dev, "aic3xxx_device_init beginning\n");
    +
    +	mutex_init(&aic3xxx->io_lock);
    +	dev_set_drvdata(aic3xxx->dev, aic3xxx);
    +
    +	pdata = devm_kzalloc(aic3xxx->dev, sizeof(*pdata), GFP_KERNEL);
    +	if (!pdata)
    +		return -ENOMEM;
    +
    +	aic3xxx->pdata = pdata;
    +	ret = aic3xxx_parse_pdata_from_of(aic3xxx);
    +	if (ret) {
    +		dev_err(aic3xxx->dev, "platform data parse failed");
    +		goto err_return;
    +	}
    +
    +	/*GPIO reset for TLV320AIC3262 codec */
    +	if (pdata->gpio_reset) {
    +		ret = gpio_request(pdata->gpio_reset, "aic3xxx-reset-pin");
    +		if (ret != 0) {
    +			dev_err(aic3xxx->dev, "not able to acquire gpio\n");
    +			goto err_return;
    +		}
    +		gpio_direction_output(pdata->gpio_reset, 1);
    +		mdelay(5);
    +		gpio_direction_output(pdata->gpio_reset, 0);
    +		mdelay(5);
    +		gpio_direction_output(pdata->gpio_reset, 1);
    +		mdelay(5);
    +	}
    +
    +	/* run the codec through software reset */
    +	ret = aic3xxx_reg_write(aic3xxx, AIC3262_RESET_REG, resetVal);
    +	if (ret < 0) {
    +		dev_err(aic3xxx->dev, "Could not write to AIC3262 register\n");
    +		goto err_return;
    +	}
    +
    +	mdelay(10);
    +
    +	ret = aic3xxx_reg_read(aic3xxx, AIC3262_DEVICE_ID);
    +	if (ret < 0) {
    +		dev_err(aic3xxx->dev, "Failed to read ID register\n");
    +		goto err_return;
    +	}
    +
    +	//TODO: //remove this
    +	ret = 3;
    +
    +	switch (ret) {
    +	case 3:
    +		devname = "TLV320AIC3262";
    +		if (aic3xxx->type != TLV320AIC3262)
    +			dev_warn(aic3xxx->dev, "Device registered as type %d\n",
    +				 aic3xxx->type);
    +		aic3xxx->type = TLV320AIC3262;
    +		break;
    +	case 4:
    +		devname = "TLV320AIC3285";
    +		if (aic3xxx->type != TLV320AIC3285)
    +			dev_warn(aic3xxx->dev, "Device registered as type %d\n",
    +				 aic3xxx->type);
    +		aic3xxx->type = TLV320AIC3285;
    +	fallthrough;
    +	default:
    +		dev_err(aic3xxx->dev, "Device is not a TLV320AIC3262");
    +		ret = -EINVAL;
    +		goto err_return;
    +	}
    +
    +	dev_info(aic3xxx->dev, "%s revision %c\n", devname, 'D' + ret);
    +
    +	/*If naudint is gpio convert it to irq number */
    +	if (pdata->gpio_irq == 1) {
    +		aic3xxx->irq = gpio_to_irq(pdata->naudint_irq);
    +		gpio_request(pdata->naudint_irq, "aic3xxx-gpio-irq");
    +		gpio_direction_input(pdata->naudint_irq);
    +	} else
    +		aic3xxx->irq = pdata->naudint_irq;
    +
    +	aic3xxx->irq_base = pdata->irq_base;
    +	for (i = 0; i < AIC3262_NUM_GPIO; i++) {
    +		if (pdata->gpio && pdata->gpio[i].used) {
    +			if (pdata->gpio[i].in) {
    +				aic3xxx_set_bits(aic3xxx,
    +						 aic3262_gpio_control[i].reg,
    +						 aic3262_gpio_control[i].mask,
    +						 0x1 << aic3262_gpio_control[i].
    +						 shift);
    +				if (pdata->gpio[i].in_reg)
    +					aic3xxx_set_bits(aic3xxx,
    +							 pdata->gpio[i].in_reg,
    +							 pdata->gpio[i].
    +							 in_reg_bitmask,
    +							 pdata->gpio[i].
    +							 value << pdata->
    +							 gpio[i].in_reg_shift);
    +			} else {
    +				aic3xxx_set_bits(aic3xxx,
    +						 aic3262_gpio_control[i].reg,
    +						 aic3262_gpio_control[i].mask,
    +						 pdata->gpio[i].
    +						 value <<
    +						 aic3262_gpio_control[i].shift);
    +			}
    +		} else
    +			aic3xxx_set_bits(aic3xxx, aic3262_gpio_control[i].reg,
    +					 aic3262_gpio_control[i].mask, 0x0);
    +	}
    +
    +	/* codec interrupt */
    +	if (aic3xxx->irq) {
    +		ret = aic3xxx_irq_init(aic3xxx);
    +		if (ret < 0)
    +			goto err_irq;
    +	}
    +	switch (aic3xxx->type) {
    +	case TLV320AIC3262:
    +		dev_info(aic3xxx->dev, "adding codec device");
    +		ret = mfd_add_devices(aic3xxx->dev, -1,
    +			      aic3262_devs, ARRAY_SIZE(aic3262_devs), NULL, 0, NULL);
    +		break;
    +
    +	case TLV320AIC3285:
    +		ret = mfd_add_devices(aic3xxx->dev, -1,
    +			      aic3285_devs, ARRAY_SIZE(aic3285_devs), NULL, 0, NULL);
    +		break;
    +	case TLV320AIC3266:
    +		break;
    +
    +	default:
    +		dev_err(aic3xxx->dev, "unable to recognize codec\n");
    +	}
    +	if (ret != 0) {
    +		dev_err(aic3xxx->dev, "Failed to add children: %d\n", ret);
    +		goto err_mfd;
    +	}
    +	dev_info(aic3xxx->dev, "aic3xxx_device_init added mfd devices\n");
    +
    +	pm_runtime_enable(aic3xxx->dev);
    +	pm_runtime_resume(aic3xxx->dev);
    +
    +	return 0;
    +
    +err_mfd:
    +
    +	aic3xxx_irq_exit(aic3xxx);
    +err_irq:
    +
    +	if (pdata && pdata->gpio_irq)
    +		gpio_free(pdata->naudint_irq);
    +err_return:
    +
    +	if (pdata && pdata->gpio_reset)
    +		gpio_free(pdata->gpio_reset);
    +
    +	return ret;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_device_init);
    +
    +void aic3xxx_device_exit(struct aic3xxx *aic3xxx)
    +{
    +	struct aic3xxx_pdata *pdata = aic3xxx->dev->platform_data;
    +
    +	pm_runtime_disable(aic3xxx->dev);
    +	mfd_remove_devices(aic3xxx->dev);
    +	aic3xxx_irq_exit(aic3xxx);
    +
    +	if (pdata && pdata->gpio_irq)
    +		gpio_free(pdata->naudint_irq);
    +	if (pdata && pdata->gpio_reset)
    +		gpio_free(pdata->gpio_reset);
    +
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_device_exit);
    +
    +MODULE_AUTHOR("Mukund Navada <navada@ti.comm>");
    +MODULE_AUTHOR("Mehar Bajwa <mehar.bajwa@ti.com>");
    +MODULE_DESCRIPTION("Core support for the TLV320AIC3XXX audio CODEC");
    +MODULE_LICENSE("GPL");
    diff --git a/drivers/mfd/tlv320aic3xxx-i2c.c b/drivers/mfd/tlv320aic3xxx-i2c.c
    new file mode 100644
    index 000000000..921106b93
    --- /dev/null
    +++ b/drivers/mfd/tlv320aic3xxx-i2c.c
    @@ -0,0 +1,142 @@
    +/*
    + * tlv320aic3xxx-i2c.c  -- driver for TLV320AIC3XXX TODO
    + *
    + * Author:	Mukund Navada <navada@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#include <linux/kernel.h>
    +#include <linux/err.h>
    +#include <linux/i2c.h>
    +#include <linux/module.h>
    +#include <linux/pm_runtime.h>
    +#include <linux/regmap.h>
    +#include <linux/regulator/consumer.h>
    +#include <linux/slab.h>
    +
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +
    +struct regmap_config aicxxx_i2c_regmap = {
    +	.reg_bits = 8,
    +	.val_bits = 8,
    +	.cache_type = REGCACHE_NONE,
    +};
    +
    +#ifdef CONFIG_PM
    +static int aic3xxx_suspend(struct device *dev)
    +{
    +	struct aic3xxx *aic3xxx = dev_get_drvdata(dev);
    +
    +	aic3xxx->suspended = true;
    +
    +	return 0;
    +}
    +
    +static int aic3xxx_resume(struct device *dev)
    +{
    +	struct aic3xxx *aic3xxx = dev_get_drvdata(dev);
    +
    +	aic3xxx->suspended = false;
    +
    +	return 0;
    +}
    +#endif
    +
    +static int aic3xxx_i2c_probe(struct i2c_client *i2c)
    +{
    +	struct aic3xxx *aicxxx;
    +	const struct regmap_config *regmap_config;
    +	int ret;
    +
    +	aicxxx = devm_kzalloc(&i2c->dev, sizeof(*aicxxx), GFP_KERNEL);
    +	if (aicxxx == NULL)
    +		return -ENOMEM;
    +	aicxxx->type = (kernel_ulong_t)i2c_get_match_data(i2c);
    +
    +	dev_info(&i2c->dev, "i2c probe");
    +
    +	switch (aicxxx->type) {
    +	case TLV320AIC3262:
    +	case TLV320AIC3268:
    +		regmap_config = &aicxxx_i2c_regmap;
    +		break;
    +	case TLV320AIC3285:
    +		regmap_config = &aicxxx_i2c_regmap;
    +		break;
    +	default:
    +		dev_err(&i2c->dev, "Unknown device type %u\n",
    +			aicxxx->type);
    +		return -EINVAL;
    +	}
    +
    +	aicxxx->regmap = devm_regmap_init_i2c(i2c, regmap_config);
    +
    +	if (IS_ERR(aicxxx->regmap)) {
    +		ret = PTR_ERR(aicxxx->regmap);
    +		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
    +			ret);
    +		return ret;
    +	}
    +
    +	aicxxx->dev = &i2c->dev;
    +	aicxxx->irq = i2c->irq;
    +
    +	return aic3xxx_device_init(aicxxx, aicxxx->irq);
    +}
    +
    +static void aic3xxx_i2c_remove(struct i2c_client *i2c)
    +{
    +	struct aic3xxx *aicxxx = dev_get_drvdata(&i2c->dev);
    +	aic3xxx_device_exit(aicxxx);
    +	//return 0;
    +}
    +
    +static const struct of_device_id tlv320aic326X_of_match[] = {
    +	{ .compatible = "ti,tlv320aic3262", .data = (void *)TLV320AIC3262 },
    +	{ .compatible = "ti,tlv320aic3268", .data = (void *)TLV320AIC3268 },
    +	{ .compatible = "ti,tlv320aic3285", .data = (void *)TLV320AIC3285 },
    +	{ },
    +};
    +
    +static const struct i2c_device_id aic3xxx_i2c_id[] = {
    +	{"tlv320aic3262", TLV320AIC3262},
    +	{"tlv320aic3268", TLV320AIC3268},
    +	{"tlv320aic3285", TLV320AIC3285},
    +	{ }
    +};
    +MODULE_DEVICE_TABLE(i2c, aic3xxx_i2c_id);
    +
    +static UNIVERSAL_DEV_PM_OPS(aic3xxx_pm_ops, aic3xxx_suspend, aic3xxx_resume,
    +				NULL);
    +
    +static struct i2c_driver aic3xxx_i2c_driver = {
    +	.driver = {
    +		.name	= "tlv320aic3xxx",
    +		.owner	= THIS_MODULE,
    +		.pm	= &aic3xxx_pm_ops,
    +		.of_match_table = of_match_ptr(tlv320aic326X_of_match),
    +	},
    +	.probe		= aic3xxx_i2c_probe,
    +	.remove		= aic3xxx_i2c_remove,
    +	.id_table	= aic3xxx_i2c_id,
    +};
    +
    +module_i2c_driver(aic3xxx_i2c_driver);
    +
    +MODULE_DESCRIPTION("TLV320AIC3XXX I2C bus interface");
    +MODULE_AUTHOR("Mukund Navada <navada@ti.com>");
    +MODULE_LICENSE("GPL");
    diff --git a/drivers/mfd/tlv320aic3xxx-irq.c b/drivers/mfd/tlv320aic3xxx-irq.c
    new file mode 100644
    index 000000000..0729ad5db
    --- /dev/null
    +++ b/drivers/mfd/tlv320aic3xxx-irq.c
    @@ -0,0 +1,222 @@
    +/*
    + * tlv320aic3262-irq.c  --  Interrupt controller support for
    + *			 TI OMAP44XX TLV320AIC3262
    + *
    + * Author:      Mukund Navada <navada@ti.com>
    + *              Mehar Bajwa <mehar.bajwa@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#include <linux/kernel.h>
    +#include <linux/module.h>
    +#include <linux/i2c.h>
    +#include <linux/irq.h>
    +#include <linux/mfd/core.h>
    +#include <linux/interrupt.h>
    +
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +#include <linux/mfd/tlv320aic3262-registers.h>
    +
    +#include <linux/delay.h>
    +
    +struct aic3262_irq_data {
    +	int mask;
    +	int status;
    +};
    +
    +static struct aic3262_irq_data aic3262_irqs[] = {
    +	{
    +	 .mask = AIC3262_HEADSET_IN_MASK,
    +	 .status = AIC3262_HEADSET_PLUG_UNPLUG_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_BUTTON_PRESS_MASK,
    +	 .status = AIC3262_BUTTON_PRESS_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_DAC_DRC_THRES_MASK,
    +	 .status = AIC3262_LEFT_DRC_THRES_INT | AIC3262_RIGHT_DRC_THRES_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_AGC_NOISE_MASK,
    +	 .status = AIC3262_LEFT_AGC_NOISE_INT | AIC3262_RIGHT_AGC_NOISE_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_OVER_CURRENT_MASK,
    +	 .status = AIC3262_LEFT_OUTPUT_DRIVER_OVERCURRENT_INT
    +	 | AIC3262_RIGHT_OUTPUT_DRIVER_OVERCURRENT_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_OVERFLOW_MASK,
    +	 .status =
    +	 AIC3262_LEFT_DAC_OVERFLOW_INT | AIC3262_RIGHT_DAC_OVERFLOW_INT |
    +	 AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT |
    +	 AIC3262_LEFT_ADC_OVERFLOW_INT | AIC3262_RIGHT_ADC_OVERFLOW_INT |
    +	 AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_SPK_OVERCURRENT_MASK,
    +	 .status = AIC3262_SPK_OVER_CURRENT_INT,
    +	 },
    +
    +};
    +
    +struct aic3262_gpio_data {
    +
    +};
    +
    +static inline struct aic3262_irq_data *irq_to_aic3262_irq(struct aic3xxx
    +							  *aic3262, int irq)
    +{
    +	return &aic3262_irqs[irq - aic3262->irq_base];
    +}
    +
    +static void aic3262_irq_lock(struct irq_data *data)
    +{
    +	struct aic3xxx *aic3262 = irq_data_get_irq_chip_data(data);
    +
    +	mutex_lock(&aic3262->irq_lock);
    +}
    +
    +static void aic3262_irq_sync_unlock(struct irq_data *data)
    +{
    +	struct aic3xxx *aic3262 = irq_data_get_irq_chip_data(data);
    +
    +	/* write back to hardware any change in irq mask */
    +	if (aic3262->irq_masks_cur != aic3262->irq_masks_cache) {
    +		aic3262->irq_masks_cache = aic3262->irq_masks_cur;
    +		aic3xxx_reg_write(aic3262, AIC3262_INT1_CNTL,
    +				  aic3262->irq_masks_cur);
    +	}
    +
    +	mutex_unlock(&aic3262->irq_lock);
    +}
    +
    +static void aic3262_irq_unmask(struct irq_data *data)
    +{
    +	struct aic3xxx *aic3262 = irq_data_get_irq_chip_data(data);
    +	struct aic3262_irq_data *irq_data =
    +	    irq_to_aic3262_irq(aic3262, data->irq);
    +
    +	aic3262->irq_masks_cur |= irq_data->mask;
    +}
    +
    +static void aic3262_irq_mask(struct irq_data *data)
    +{
    +	struct aic3xxx *aic3262 = irq_data_get_irq_chip_data(data);
    +	struct aic3262_irq_data *irq_data =
    +	    irq_to_aic3262_irq(aic3262, data->irq);
    +
    +	aic3262->irq_masks_cur &= ~irq_data->mask;
    +}
    +
    +static struct irq_chip aic3262_irq_chip = {
    +	.name = "tlv320aic3262",
    +	.irq_bus_lock = aic3262_irq_lock,
    +	.irq_bus_sync_unlock = aic3262_irq_sync_unlock,
    +	.irq_mask = aic3262_irq_mask,
    +	.irq_unmask = aic3262_irq_unmask,
    +};
    +
    +static irqreturn_t aic3262_irq_thread(int irq, void *data)
    +{
    +	struct aic3xxx *aic3262 = data;
    +	u8 status[4];
    +
    +	/* Reading sticky bit registers acknowledges
    +		the interrupt to the device */
    +	aic3xxx_bulk_read(aic3262, AIC3262_INT_STICKY_FLAG1, 4, status);
    +
    +	/* report  */
    +	if (status[2] & aic3262_irqs[AIC3262_IRQ_HEADSET_DETECT].status)
    +		handle_nested_irq(aic3262->irq_base);
    +	if (status[2] & aic3262_irqs[AIC3262_IRQ_BUTTON_PRESS].status)
    +		handle_nested_irq(aic3262->irq_base + 1);
    +	if (status[2] & aic3262_irqs[AIC3262_IRQ_DAC_DRC].status)
    +		handle_nested_irq(aic3262->irq_base + 2);
    +	if (status[3] & aic3262_irqs[AIC3262_IRQ_AGC_NOISE].status)
    +		handle_nested_irq(aic3262->irq_base + 3);
    +	if (status[2] & aic3262_irqs[AIC3262_IRQ_OVER_CURRENT].status)
    +		handle_nested_irq(aic3262->irq_base + 4);
    +	if (status[0] & aic3262_irqs[AIC3262_IRQ_OVERFLOW_EVENT].status)
    +		handle_nested_irq(aic3262->irq_base + 5);
    +	if (status[3] & aic3262_irqs[AIC3262_IRQ_SPEAKER_OVER_TEMP].status)
    +		handle_nested_irq(aic3262->irq_base + 6);
    +
    +	/* ack unmasked irqs */
    +	/* No need to acknowledge the interrupt on AIC3262 */
    +
    +	return IRQ_HANDLED;
    +}
    +
    +int aic3xxx_irq_init(struct aic3xxx *aic3262)
    +{
    +	int cur_irq, ret;
    +
    +	mutex_init(&aic3262->irq_lock);
    +
    +	/* mask the individual interrupt sources */
    +	aic3262->irq_masks_cur = 0x0;
    +	aic3262->irq_masks_cache = 0x0;
    +	aic3xxx_reg_write(aic3262, AIC3262_INT1_CNTL, 0x0);
    +
    +	if (!aic3262->irq) {
    +		dev_warn(aic3262->dev,
    +			 "no interrupt specified, no interrupts\n");
    +		aic3262->irq_base = 0;
    +		return 0;
    +	}
    +
    +	if (!aic3262->irq_base) {
    +		dev_err(aic3262->dev,
    +			"no interrupt base specified, no interrupts\n");
    +		return 0;
    +	}
    +
    +	/* Register them with genirq */
    +	for (cur_irq = aic3262->irq_base;
    +	     cur_irq < aic3262->irq_base + ARRAY_SIZE(aic3262_irqs);
    +	     cur_irq++) {
    +		irq_set_chip_data(cur_irq, aic3262);
    +		irq_set_chip_and_handler(cur_irq, &aic3262_irq_chip,
    +					 handle_edge_irq);
    +		irq_set_nested_thread(cur_irq, 1);
    +	}
    +	ret = request_threaded_irq(aic3262->irq, NULL, aic3262_irq_thread,
    +				   IRQF_TRIGGER_RISING,
    +				   "tlv320aic3262", aic3262);
    +	if (ret < 0) {
    +		dev_err(aic3262->dev, "failed to request IRQ %d: %d\n",
    +			aic3262->irq, ret);
    +		return ret;
    +	}
    +
    +	return 0;
    +}
    +EXPORT_SYMBOL(aic3xxx_irq_init);
    +
    +void aic3xxx_irq_exit(struct aic3xxx *aic3262)
    +{
    +	if (aic3262->irq)
    +		free_irq(aic3262->irq, aic3262);
    +}
    +EXPORT_SYMBOL(aic3xxx_irq_exit);
    +MODULE_AUTHOR("Mukund navada <navada@ti.com>");
    +MODULE_AUTHOR("Mehar Bajwa <mehar.bajwa@ti.com>");
    +MODULE_DESCRIPTION
    +	("Interrupt controller support for TI OMAP44XX TLV320AIC3262");
    +MODULE_LICENSE("GPL");
    diff --git a/drivers/mfd/tlv320aic3xxx-spi.c b/drivers/mfd/tlv320aic3xxx-spi.c
    new file mode 100644
    index 000000000..a148bc603
    --- /dev/null
    +++ b/drivers/mfd/tlv320aic3xxx-spi.c
    @@ -0,0 +1,91 @@
    +
    +#include <linux/err.h>
    +#include <linux/module.h>
    +#include <linux/pm_runtime.h>
    +#include <linux/regmap.h>
    +#include <linux/regulator/consumer.h>
    +#include <linux/slab.h>
    +#include <linux/spi/spi.h>
    +
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +
    +struct regmap_config tlv320aic3xxx_spi_regmap = {
    +	.reg_bits = 8,
    +	.val_bits = 8,
    +	.cache_type = REGCACHE_NONE,
    +	.read_flag_mask = 0x1,
    +};
    +
    +static int tlv320aic3xxx_spi_probe(struct spi_device *spi)
    +{
    +	const struct spi_device_id *id = spi_get_device_id(spi);
    +	struct aic3xxx *tlv320aic3xxx;
    +	const struct regmap_config *regmap_config;
    +	int ret;
    +
    +	switch (id->driver_data) {
    +#ifdef CONFIG_SND_SOC_AIC3262
    +	case TLV320AIC3262:
    +		regmap_config = &tlv320aic3xxx_spi_regmap;
    +		break;
    +#endif
    +#ifdef CONFIG_MFD_AIC3285
    +	case TLV320AIC3285:
    +		regmap_config = &tlv320aic3285_spi_regmap;
    +		break;
    +#endif
    +	default:
    +		dev_err(&spi->dev, "Unknown device type %ld\n",
    +			id->driver_data);
    +		return -EINVAL;
    +	}
    +
    +	tlv320aic3xxx = devm_kzalloc(&spi->dev, sizeof(struct aic3xxx),
    +				    GFP_KERNEL);
    +	if (tlv320aic3xxx == NULL)
    +		return -ENOMEM;
    +
    +	tlv320aic3xxx->regmap = devm_regmap_init_spi(spi, regmap_config);
    +	if (IS_ERR(tlv320aic3xxx->regmap)) {
    +		ret = PTR_ERR(tlv320aic3xxx->regmap);
    +		dev_err(&spi->dev, "Failed to allocate register map: %d\n",
    +			ret);
    +		return ret;
    +	}
    +
    +	tlv320aic3xxx->type = id->driver_data;
    +	tlv320aic3xxx->dev = &spi->dev;
    +	tlv320aic3xxx->irq = spi->irq;
    +
    +	return aic3xxx_device_init(tlv320aic3xxx, tlv320aic3xxx->irq);
    +}
    +
    +static int tlv320aic3xxx_spi_remove(struct spi_device *spi)
    +{
    +	struct aic3xxx *tlv320aic3xxx = dev_get_drvdata(&spi->dev);
    +	aic3xxx_device_exit(tlv320aic3xxx);
    +	return 0;
    +}
    +
    +static const struct spi_device_id aic3xxx_spi_ids[] = {
    +	{"tlv320aic3262", TLV320AIC3262},
    +	{"tlv320aic3285", TLV320AIC3285},
    +	{ }
    +};
    +MODULE_DEVICE_TABLE(spi, aic3xxx_spi_ids);
    +
    +static struct spi_driver tlv320aic3xxx_spi_driver = {
    +	.driver = {
    +		.name	= "tlv320aic3xxx",
    +		.owner	= THIS_MODULE,
    +	},
    +	.probe		= tlv320aic3xxx_spi_probe,
    +	.remove		= tlv320aic3xxx_spi_remove,
    +	.id_table	= aic3xxx_spi_ids,
    +};
    +
    +module_spi_driver(tlv320aic3xxx_spi_driver);
    +
    +MODULE_DESCRIPTION("TLV320AIC3XXX SPI bus interface");
    +MODULE_AUTHOR("Mukund Navada <navada@ti.com>");
    +MODULE_LICENSE("GPL");
    diff --git a/include/linux/mfd/tlv320aic3262-registers.h b/include/linux/mfd/tlv320aic3262-registers.h
    new file mode 100644
    index 000000000..7b91ee574
    --- /dev/null
    +++ b/include/linux/mfd/tlv320aic3262-registers.h
    @@ -0,0 +1,342 @@
    +
    +/*
    + *tlv320aic3262-registers: Register bits for AIC3262 codecs
    + *
    + *
    + * Author:      Mukund Navada <navada@ti.com>
    + *              Mehar Bajwa <mehar.bajwa@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#ifndef __MFD_AIC3262_REGISTERS_H__
    +#define __MFD_AIC3262_REGISTERS_H__
    +
    +#define MAKE_REG(book, page, offset) \
    +	(unsigned int)((book << 16)|(page << 8)|offset)
    +
    +/* ****************** Book 0 Registers **************************************/
    +
    +/* ****************** Page 0 Registers **************************************/
    +#define AIC3262_PAGE_SEL_REG		MAKE_REG(0, 0, 0)
    +#define AIC3262_RESET_REG		MAKE_REG(0, 0, 1)
    +#define AIC3262_REV_PG_ID		MAKE_REG(0, 0, 2)
    +#define AIC3262_REV_MASK		(0b01110000)
    +#define AIC3262_REV_SHIFT		4
    +#define AIC3262_PG_MASK			(0b00000111)
    +#define AIC3262_PG_SHIFT		0
    +#define AIC3262_DAC_ADC_CLKIN_REG	MAKE_REG(0, 0, 4)
    +#define AIC3262_PLL_CLKIN_REG		MAKE_REG(0, 0, 5)
    +#define AIC3262_PLL_CLKIN_MASK		(0b00111100)
    +#define AIC3262_PLL_CLKIN_SHIFT		2
    +#define AIC3262_PLL_CLKIN_MCLK1		0
    +#define AIC3262_PLL_CLKIN_BCLK1		1
    +#define AIC3262_PLL_CLKIN_GPIO1		2
    +#define AIC3262_PLL_CLKIN_DIN1		3
    +#define AIC3262_PLL_CLKIN_BCLK2		4
    +#define AIC3262_PLL_CLKIN_GPI1		5
    +#define AIC3262_PLL_CLKIN_HF_REF_CLK	6
    +#define AIC3262_PLL_CLKIN_GPIO2		7
    +#define AIC3262_PLL_CLKIN_GPI2		8
    +#define AIC3262_PLL_CLKIN_MCLK2		9
    +#define AIC3262_CLK_VAL_MASK		0x7f
    +#define AIC3262_PLL_CLK_RANGE_REG	MAKE_REG(0, 0, 5)
    +#define AIC3262_PLL_PR_POW_REG		MAKE_REG(0, 0, 6)
    +#define AIC3262_PLL_PVAL_MASK		0x70
    +#define AIC3262_PLL_RVAL_MASK		0x0F
    +
    +#define AIC3262_ENABLE_CLK_MASK		0x80
    +#define AIC3262_ENABLE_CLK		0x80
    +
    +#define AIC3262_PLL_J_REG		MAKE_REG(0, 0, 7)
    +#define AIC3262_JVAL_MASK		0x3f
    +#define AIC3262_PLL_D_MSB		MAKE_REG(0, 0, 8)
    +#define AIC3262_DVAL_MSB_MASK		0xf
    +#define AIC3262_DVAL_LSB_MASK		0xff
    +#define AIC3262_PLL_D_LSB		MAKE_REG(0, 0, 9)
    +#define AIC3262_PLL_CKIN_DIV		MAKE_REG(0, 0, 10)
    +
    +#define AIC3262_NDAC_DIV_POW_REG	MAKE_REG(0, 0, 11)
    +#define AIC3262_MDAC_DIV_POW_REG	MAKE_REG(0, 0, 12)
    +#define AIC3262_DOSR_MSB_REG		MAKE_REG(0, 0, 13)
    +#define AIC3262_DOSR_MSB_MASK		0x3
    +#define AIC3262_DOSR_LSB_REG		MAKE_REG(0, 0, 14)
    +#define AIC3262_DOSR_LSB_MASK		0xFF
    +
    +#define AIC3262_NADC_DIV_POW_REG	MAKE_REG(0, 0, 18)
    +#define AIC3262_MADC_DIV_POW_REG	MAKE_REG(0, 0, 19)
    +#define AIC3262_AOSR_REG		MAKE_REG(0, 0, 20)
    +#define AIC3262_CLKOUT_MUX		MAKE_REG(0, 0, 21)
    +#define AIC3262_CLKOUT_MDIV_VAL		MAKE_REG(0, 0, 22)
    +#define AIC3262_TIMER_REG		MAKE_REG(0, 0, 23)
    +
    +#define AIC3262_LF_CLK_CNTL		MAKE_REG(0, 0, 24)
    +#define AIC3262_HF_CLK_CNTL_R1		MAKE_REG(0, 0, 25)
    +#define AIC3262_HF_CLK_CNTL_R2		MAKE_REG(0, 0, 26)
    +#define AIC3262_HF_CLK_CNTL_R3		MAKE_REG(0, 0, 27)
    +#define AIC3262_HF_CLK_CNTL_R4		MAKE_REG(0, 0, 28)
    +#define AIC3262_HF_CLK_TRIM_R1		MAKE_REG(0, 0, 29)
    +#define AIC3262_HF_CLK_TRIM_R2		MAKE_REG(0, 0, 30)
    +#define AIC3262_HF_CLK_TRIM_R3		MAKE_REG(0, 0, 31)
    +#define AIC3262_HF_CLK_TRIM_R4		MAKE_REG(0, 0, 32)
    +#define AIC3262_LDAC_POWER_STATUS_MASK		0x80
    +#define AIC3262_RDAC_POWER_STATUS_MASK		0x08
    +#define AIC3262_DAC_POWER_MASK		0x88
    +#define AIC3262_DAC_FLAG		MAKE_REG(0, 0, 37)
    +#define AIC3262_LADC_POWER_MASK		0x40
    +#define AIC3262_RADC_POWER_MASK		0x04
    +#define AIC3262_ADC_POWER_MASK		0x44
    +#define AIC3262_ADC_FLAG                MAKE_REG(0, 0, 36)
    +#define AIC3262_JACK_WITH_STEREO_HS	(0b00000010)
    +#define AIC3262_JACK_WITH_MIC		(0b00110000)
    +#define AIC3262_HEADSET_NOT_INSERTED	(0b00000011)
    +#define AIC3262_JACK_TYPE_MASK		(0b00110000) 
    +#define AIC3262_JACK_NOT_INSERTED	(0b00000000)
    +#define AIC3262_JACK_WITHOUT_MIC	(0b00010000)
    +
    +#define AIC3262_INT_STICKY_FLAG1		MAKE_REG(0, 0, 42)
    +#define AIC3262_LEFT_DAC_OVERFLOW_INT	0x80
    +#define AIC3262_RIGHT_DAC_OVERFLOW_INT	0x40
    +#define AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT	0x20
    +#define AIC3262_LEFT_ADC_OVERFLOW_INT	0x08
    +#define AIC3262_RIGHT_ADC_OVERFLOW_INT	0x04
    +#define AIC3262_MINIDSP_A_BARREL_SHIFT_OVERFLOW_INT	0x02
    +#define AIC3262_INT_STICKY_FLAG2		MAKE_REG(0, 0, 44)
    +#define AIC3262_LEFT_OUTPUT_DRIVER_OVERCURRENT_INT	0x80
    +#define AIC3262_RIGHT_OUTPUT_DRIVER_OVERCURRENT_INT	0x40
    +#define AIC3262_BUTTON_PRESS_INT			0x20
    +#define AIC3262_HEADSET_PLUG_UNPLUG_INT			0x10
    +#define AIC3262_LEFT_DRC_THRES_INT			0x08
    +#define AIC3262_RIGHT_DRC_THRES_INT			0x04
    +#define AIC3262_MINIDSP_D_STD_INT			0x02
    +#define AIC3262_RIGHT_DRC_AUX_INT			0x01
    +#define AIC3262_INT_STICKY_FLAG3		MAKE_REG(0, 0, 45)
    +#define AIC3262_SPK_OVER_CURRENT_INT		0x80
    +#define AIC3262_LEFT_AGC_NOISE_INT			0x40
    +#define AIC3262_RIGHT_AGC_NOISE_INT			0x20
    +#define AIC3262_INT1_CNTL		MAKE_REG(0, 0, 48)
    +#define AIC3262_HEADSET_IN_MASK		0x80
    +#define AIC3262_BUTTON_PRESS_MASK	0x40
    +#define AIC3262_DAC_DRC_THRES_MASK	0x20
    +#define AIC3262_AGC_NOISE_MASK		0x10
    +#define AIC3262_OVER_CURRENT_MASK	0x08
    +#define AIC3262_OVERFLOW_MASK		0x04
    +#define AIC3262_SPK_OVERCURRENT_MASK	0x02
    +#define AIC3262_INT2_CNTL		MAKE_REG(0, 0, 49)
    +#define AIC3262_INT_FMT			MAKE_REG(0, 0, 51)
    +
    +#define AIC3262_DAC_PRB			MAKE_REG(0, 0, 60)
    +#define AIC3262_ADC_PRB			MAKE_REG(0, 0, 61)
    +#define AIC3262_PASI_DAC_DP_SETUP	MAKE_REG(0, 0, 63)
    +
    +#define AIC3262_DAC_MVOL_CONF		MAKE_REG(0, 0, 64)
    +#define AIC3262_DAC_LR_MUTE_MASK	0xc
    +#define AIC3262_DAC_LR_MUTE		0xc
    +
    +#define AIC3262_DAC_LVOL		MAKE_REG(0, 0, 65)
    +#define AIC3262_DAC_RVOL		MAKE_REG(0, 0, 66)
    +#define AIC3262_HP_DETECT		MAKE_REG(0, 0, 67)
    +#define AIC3262_DRC_CNTL_R1		MAKE_REG(0, 0, 68)
    +#define AIC3262_DRC_CNTL_R2		MAKE_REG(0, 0, 69)
    +#define AIC3262_DRC_CNTL_R3		MAKE_REG(0, 0, 70)
    +#define AIC3262_BEEP_CNTL_R1		MAKE_REG(0, 0, 71)
    +#define AIC3262_BEEP_CNTL_R2		MAKE_REG(0, 0, 72)
    +
    +#define AIC3262_ADC_CHANNEL_POW		MAKE_REG(0, 0, 81)
    +#define AIC3262_ADC_FINE_GAIN		MAKE_REG(0, 0, 82)
    +#define AIC3262_LADC_VOL		MAKE_REG(0, 0, 83)
    +#define AIC3262_RADC_VOL		MAKE_REG(0, 0, 84)
    +#define AIC3262_ADC_PHASE		MAKE_REG(0, 0, 85)
    +
    +#define AIC3262_LAGC_CNTL		MAKE_REG(0, 0, 86)
    +#define AIC3262_LAGC_CNTL_R2		MAKE_REG(0, 0, 87)
    +#define AIC3262_LAGC_CNTL_R3		MAKE_REG(0, 0, 88)
    +#define AIC3262_LAGC_CNTL_R4		MAKE_REG(0, 0, 89)
    +#define AIC3262_LAGC_CNTL_R5		MAKE_REG(0, 0, 90)
    +#define AIC3262_LAGC_CNTL_R6		MAKE_REG(0, 0, 91)
    +#define AIC3262_LAGC_CNTL_R7		MAKE_REG(0, 0, 92)
    +#define AIC3262_LAGC_CNTL_R8		MAKE_REG(0, 0, 93)
    +
    +#define AIC3262_RAGC_CNTL		MAKE_REG(0, 0, 94)
    +#define AIC3262_RAGC_CNTL_R2		MAKE_REG(0, 0, 95)
    +#define AIC3262_RAGC_CNTL_R3		MAKE_REG(0, 0, 96)
    +#define AIC3262_RAGC_CNTL_R4		MAKE_REG(0, 0, 97)
    +#define AIC3262_RAGC_CNTL_R5		MAKE_REG(0, 0, 98)
    +#define AIC3262_RAGC_CNTL_R6		MAKE_REG(0, 0, 99)
    +#define AIC3262_RAGC_CNTL_R7		MAKE_REG(0, 0, 100)
    +#define AIC3262_RAGC_CNTL_R8		MAKE_REG(0, 0, 101)
    +#define AIC3262_MINIDSP_ACCESS_CTRL	MAKE_REG(0, 0, 121)
    +#define AIC3262_DEVICE_ID		MAKE_REG(0, 0, 125)
    +/* ****************** Page 1 Registers **************************************/
    +#define AIC3262_PAGE_1			128
    +
    +#define AIC3262_POWER_CONF		MAKE_REG(0, 1, 1)
    +
    +#define AIC3262_AVDD_TO_DVDD_MASK	(0b00001000)
    +#define	AIC3262_AVDD_TO_DVDD		0x8
    +#define AIC3262_EXT_ANALOG_SUPPLY_MASK	(0b00000100)
    +#define	AIC3262_EXT_ANALOG_SUPPLY_OFF	0x4
    +
    +#define AIC3262_LDAC_PTM		MAKE_REG(0, 1, 3)
    +#define AIC3262_RDAC_PTM		MAKE_REG(0, 1, 4)
    +#define AIC3262_CM_REG			MAKE_REG(0, 1, 8)
    +#define AIC3262_HP_CTL			MAKE_REG(0, 1, 9)
    +#define AIC3262_HP_DEPOP		MAKE_REG(0, 1, 11)
    +#define AIC3262_RECV_DEPOP		MAKE_REG(0, 1, 12)
    +#define AIC3262_MA_CNTL			MAKE_REG(0, 1, 17)
    +#define AIC3262_LADC_PGA_MAL_VOL	MAKE_REG(0, 1, 18)
    +#define AIC3262_RADC_PGA_MAR_VOL	MAKE_REG(0, 1, 19)
    +
    +#define AIC3262_LINE_AMP_CNTL_R1	MAKE_REG(0, 1, 22)
    +#define AIC3262_LINE_AMP_CNTL_R2	MAKE_REG(0, 1, 23)
    +
    +#define AIC3262_HP_AMP_CNTL_R1		MAKE_REG(0, 1, 27)
    +#define AIC3262_HP_AMP_CNTL_R2		MAKE_REG(0, 1, 28)
    +#define AIC3262_HP_AMP_CNTL_R3		MAKE_REG(0, 1, 29)
    +
    +#define AIC3262_HPL_VOL			MAKE_REG(0, 1, 31)
    +#define AIC3262_HPR_VOL			MAKE_REG(0, 1, 32)
    +#define AIC3262_INT1_SEL_L		MAKE_REG(0, 1, 34)
    +#define AIC3262_CHARGE_PUMP_CNTL	MAKE_REG(0, 1, 35)
    +#define AIC3262_RAMP_CNTL_R1		MAKE_REG(0, 1, 36)
    +#define AIC3262_RAMP_CNTL_R2		MAKE_REG(0, 1, 37)
    +#define AIC3262_IN1L_SEL_RM		MAKE_REG(0, 1, 38)
    +#define AIC3262_IN1R_SEL_RM		MAKE_REG(0, 1, 39)
    +#define AIC3262_REC_AMP_CNTL_R5		MAKE_REG(0, 1, 40)
    +#define AIC3262_RAMPR_VOL		MAKE_REG(0, 1, 41)
    +#define AIC3262_RAMP_TIME_CNTL		MAKE_REG(0, 1, 42)
    +#define AIC3262_SPK_AMP_CNTL_R1		MAKE_REG(0, 1, 45)
    +#define AIC3262_SPK_AMP_CNTL_R2		MAKE_REG(0, 1, 46)
    +#define AIC3262_SPK_AMP_CNTL_R3		MAKE_REG(0, 1, 47)
    +#define AIC3262_SPK_AMP_CNTL_R4		MAKE_REG(0, 1, 48)
    +#define AIC3262_MIC_BIAS_CNTL		MAKE_REG(0, 1, 51)
    +
    +#define AIC3262_LMIC_PGA_PIN		MAKE_REG(0, 1, 52)
    +#define AIC3262_LMIC_PGA_PM_IN4		MAKE_REG(0, 1, 53)
    +#define AIC3262_LMIC_PGA_MIN		MAKE_REG(0, 1, 54)
    +#define AIC3262_RMIC_PGA_PIN		MAKE_REG(0, 1, 55)
    +#define AIC3262_RMIC_PGA_PM_IN4		MAKE_REG(0, 1, 56)
    +#define AIC3262_RMIC_PGA_MIN		MAKE_REG(0, 1, 57)
    +#define AIC3262_HP_FLAG		        MAKE_REG(0, 1, 66)
    +#define AIC3262_SPKL_POWER_MASK		0x2
    +#define AIC3262_SPKR_POWER_MASK		0x1
    +#define AIC3262_HPL_POWER_MASK		(0b00000010)
    +#define AIC3262_HPR_POWER_MASK		(0b00000001)
    +#define AIC3262_SPKL_POWER_STATUS_MASK		0x2
    +#define AIC3262_SPKR_POWER_STATUS_MASK		0x1
    +#define AIC3262_HPL_POWER_STATUS_MASK		0x20
    +#define AIC3262_HPR_POWER_STATUS_MASK		0x10
    +
    +#define AIC3262_HP_STAGE_MASK		(0b01100000)
    +#define AIC3262_HP_STAGE_100		(0)
    +#define AIC3262_HP_STAGE_75		(1)
    +#define AIC3262_HP_STAGE_50		(2)
    +#define AIC3262_HP_STAGE_25		(3)
    +#define AIC3262_HP_STAGE_SHIFT		(5)
    +#define AIC3262_DYNAMIC_OFFSET_CALIB_MASK	(0b00100000)
    +#define AIC3262_DYNAMIC_OFFSET_CALIB		(0b00100000)
    +
    +/* MIC PGA Gain Registers */
    +#define AIC3262_MICL_PGA		MAKE_REG(0, 1, 59)
    +#define AIC3262_MICR_PGA		MAKE_REG(0, 1, 60)
    +#define AIC3262_HEADSET_TUNING1_REG	MAKE_REG(0, 1, 119)
    +#define AIC3262_HEADSET_DETECTOR_PULSE_MASK (0b11000000)
    +#define AIC3262_HEADSET_DETECTOR_PULSE_RESET (0b10000000)
    +#define AIC3262_MIC_PWR_DLY		MAKE_REG(0, 1, 121)
    +#define AIC3262_REF_PWR_DLY		MAKE_REG(0, 1, 122)
    +#define AIC3262_CHIP_REF_PWR_ON_MASK	0x4
    +#define AIC3262_CHIP_REF_PWR_ON		0x4
    +/* ****************** Page 4 Registers **************************************/
    +#define AIC3262_PAGE_4			512
    +#define AIC3262_ASI1_BUS_FMT		MAKE_REG(0, 4, 1)
    +#define AIC3262_ASI_SELECTION_MASK	(0b11100000)
    +#define AIC3262_ASI_DATA_WORD_LENGTH_MASK	(0b00011000)
    +#define AIC3262_ASI1_BCLK_N_MASK	(0b01111111)
    +#define AIC3262_ASI1_WCLK_N_MASK	(0b01111111)
    +#define AIC3262_ASI1_CHNL_MASK		(0b11000000)
    +#define AIC3262_ASI1_DAC_OUT_OFFSET	(0b00000001)
    +#define AIC3262_ASI1_LCH_OFFSET		MAKE_REG(0, 4, 2)
    +#define AIC3262_ASI1_RCH_OFFSET		MAKE_REG(0, 4, 3)
    +#define AIC3262_ASI1_CHNL_SETUP		MAKE_REG(0, 4, 4)
    +#define AIC3262_ASI1_MULTI_CH_SETUP_R1	MAKE_REG(0, 4, 5)
    +#define AIC3262_ASI1_MULTI_CH_SETUP_R2	MAKE_REG(0, 4, 6)
    +#define AIC3262_ASI1_ADC_INPUT_CNTL	MAKE_REG(0, 4, 7)
    +#define AIC3262_ASI1_DAC_OUT_CNTL	MAKE_REG(0, 4, 8)
    +#define AIC3262_ASI1_ADC_OUT_TRISTATE	MAKE_REG(0, 4, 9)
    +#define AIC3262_ASI1_BWCLK_CNTL_REG	MAKE_REG(0, 4, 10)
    +#define AIC3262_ASI1_BCLK_N_CNTL	MAKE_REG(0, 4, 11)
    +#define AIC3262_ASI1_BCLK_N		MAKE_REG(0, 4, 12)
    +#define AIC3262_ASI1_WCLK_N		MAKE_REG(0, 4, 13)
    +#define AIC3262_ASI1_BWCLK_OUT_CNTL	MAKE_REG(0, 4, 14)
    +#define AIC3262_ASI1_DOUT_CNTL		MAKE_REG(0, 4, 15)
    +#define AIC3262_ASI2_BUS_FMT	        MAKE_REG(0, 4, 17)
    +#define AIC3262_ASI2_LCH_OFFSET		MAKE_REG(0, 4, 18)
    +#define AIC3262_ASI2_ADC_INPUT_CNTL	MAKE_REG(0, 4, 23)
    +#define AIC3262_ASI2_DAC_OUT_CNTL	MAKE_REG(0, 4, 24)
    +#define AIC3262_ASI2_BWCLK_CNTL_REG	MAKE_REG(0, 4, 26)
    +#define AIC3262_ASI2_BCLK_N_CNTL	MAKE_REG(0, 4, 27)
    +#define AIC3262_ASI2_BCLK_N		MAKE_REG(0, 4, 28)
    +#define AIC3262_ASI2_WCLK_N		MAKE_REG(0, 4, 29)
    +#define AIC3262_ASI2_BWCLK_OUT_CNTL	MAKE_REG(0, 4, 30)
    +#define AIC3262_ASI2_DOUT_CNTL		MAKE_REG(0, 4, 31)
    +#define AIC3262_ASI3_BUS_FMT		MAKE_REG(0, 4, 33)
    +#define AIC3262_ASI3_LCH_OFFSET		MAKE_REG(0, 4, 34)
    +#define AIC3262_ASI3_ADC_INPUT_CNTL	MAKE_REG(0, 4, 39)
    +#define AIC3262_ASI3_DAC_OUT_CNTL	MAKE_REG(0, 4, 40)
    +#define AIC3262_ASI3_BWCLK_CNTL_REG	MAKE_REG(0, 4, 42)
    +#define AIC3262_ASI3_BCLK_N_CNTL	MAKE_REG(0, 4, 43)
    +#define AIC3262_ASI3_BCLK_N		MAKE_REG(0, 4, 44)
    +#define AIC3262_ASI3_WCLK_N		MAKE_REG(0, 4, 45)
    +#define AIC3262_ASI3_BWCLK_OUT_CNTL	MAKE_REG(0, 4, 46)
    +#define AIC3262_ASI3_DOUT_CNTL		MAKE_REG(0, 4, 47)
    +#define AIC3262_DMIC_INPUT_CNTL		MAKE_REG(0, 4, 101)
    +#define AIC3262_GPIO1_IO_CNTL		MAKE_REG(0, 4, 86)
    +#define AIC3262_GPIO_D6_D2		(0b01111100)
    +#define AIC3262_GPIO_D2_SHIFT		(2)
    +#define AIC3262_GPIO_D1_SHIFT		(1)
    +#define AIC3262_GPIO_D4_SHIFT		(4)
    +#define AIC3262_GPIO2_IO_CNTL		MAKE_REG(0, 4, 87)
    +#define AIC3262_GPI1_EN			MAKE_REG(0, 4, 91)
    +#define AIC3262_GPI1_D2_D1		(0b00000110)
    +#define AIC3262_GPI2_D5_D4		(0b00110000)
    +#define AIC3262_GPI2_EN			MAKE_REG(0, 4, 92)
    +#define AIC3262_GPO1_OUT_CNTL		MAKE_REG(0, 4, 96)
    +#define AIC3262_GPO1_D4_D1		(0b00011110)
    +#define AIC3262_DMIC_INPUT_CONTROL	MAKE_REG(0, 4, 101)
    +#define AIC3262_DMIC_CONFIGURE_MASK	(0b00011111)
    +#define AIC3262_DMIC_CONFIGURE_SHIFT	(0)
    +#define AIC3262_DMIC_GPI2_LEFT_GPI2_RIGHT	(1)
    +#define AIC3262_MINIDSP_DATA_PORT_CNTL	MAKE_REG(0, 4, 118)
    +
    +#define AIC3262_DAC_ASI_LR_UNMUTE_MASK	0x50
    +#define AIC3262_DAC_ASI_LR_UNMUTE	0x50
    +#define AIC3262_WCLK_BCLK_MASTER_MASK (0b00100110)
    +#define AIC3262_WCLK_MASTER_MASK (0b00100000)
    +#define AIC3262_BCLK_MASTER_MASK (0b00000100)
    +#define AIC3262_BCLK_OFFSET_MASK (0b11111111)
    +#define AIC3262_ASI_INTERFACE_MASK (0b11100000)
    +#define AIC3262_WCLK_OUT_MASK (0b00100000)
    +#define AIC3262_BCLK_OUT_MASK (0b00000100)
    +#define AIC3262_BCLK_INV_MASK (0b00000010)
    +
    +#define AIC3262_ADC_ADAPTIVE_CRAM_REG    MAKE_REG(40, 0, 1)
    +#define AIC3262_DAC_ADAPTIVE_BANK1_REG   MAKE_REG(80, 0, 1)
    +#define AIC3262_DAC_ADAPTIVE_BANK2_REG   MAKE_REG(82, 0, 1)
    +#define AIC3262_ADC_DATAPATH_SETUP      MAKE_REG(0, 0, 81)
    +#define AIC3262_DAC_DATAPATH_SETUP      MAKE_REG(0, 0, 63)
    +
    +#endif
    +
    diff --git a/include/linux/mfd/tlv320aic3xxx-core.h b/include/linux/mfd/tlv320aic3xxx-core.h
    new file mode 100644
    index 000000000..f6359f3a1
    --- /dev/null
    +++ b/include/linux/mfd/tlv320aic3xxx-core.h
    @@ -0,0 +1,291 @@
    +/*
    + * MFD driver for aic3262
    + *
    + * Author:      Mukund Navada <navada@ti.com>
    + *              Mehar Bajwa <mehar.bajwa@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#ifndef __MFD_AIC3262_CORE_H__
    +#define __MFD_AIC3262_CORE_H__
    +
    +#include <linux/interrupt.h>
    +#include <linux/mfd/core.h>
    +enum aic3xxx_type {
    +	TLV320AIC3262 = 0,
    +	TLV320AIC3266 = 1,
    +	TLV320AIC3285 = 2,
    +	TLV320AIC3268 = 3,
    +};
    +
    +#define AIC3262_IRQ_HEADSET_DETECT	0
    +#define AIC3262_IRQ_BUTTON_PRESS	1
    +#define AIC3262_IRQ_DAC_DRC		2
    +#define AIC3262_IRQ_AGC_NOISE		3
    +#define AIC3262_IRQ_OVER_CURRENT	4
    +#define AIC3262_IRQ_OVERFLOW_EVENT	5
    +#define AIC3262_IRQ_SPEAKER_OVER_TEMP	6
    +
    +#define AIC3262_GPIO1			7
    +#define AIC3262_GPIO2			8
    +#define AIC3262_GPI1			9
    +#define AIC3262_GPI2			10
    +#define AIC3262_GPO1			11
    +#define AIC3285_GPIO3			9
    +#define AIC3285_GPIO4			10
    +#define AIC3285_GPIO5			11
    +#define AIC3285_GPIO6			12
    +#define AIC3285_GPIO7			13
    +#define AIC3285_GPIO8			14
    +#define AIC3285_GPIO9			15
    +#define AIC3285_GPIO10			16
    +#define AIC3285_GPIO11			17
    +#define AIC3285_GPIO12			18
    +#define AIC3285_GPO1			19
    +
    +struct aic3262_codec_data {
    +	u16 hs_left_step;
    +	u16 hs_right_step;
    +	u16 hf_left_step;
    +	u16 hf_right_step;
    +};
    +
    +struct aic3262_platform_data {
    +	int audpwron_gpio;	/* audio power-on gpio */
    +	unsigned int irq_base;
    +
    +	struct aic3262_codec_data *codec;
    +};
    +
    +union aic3xxx_reg_union {
    +	struct aic3xxx_reg {
    +		u8 offset;
    +		u8 page;
    +		u8 book;
    +		u8 reserved;
    +	} aic3xxx_register;
    +	unsigned int aic3xxx_register_int;
    +};
    +
    +/****************************             ************************************/
    +
    +/*
    + *****************************************************************************
    + * Structures Definitions
    + *****************************************************************************
    + */
    +/*
    + *----------------------------------------------------------------------------
    + * @struct  aic3262_setup_data |
    + *          i2c specific data setup for AIC3262.
    + * @field   unsigned short |i2c_address |
    + *          Unsigned short for i2c address.
    + *----------------------------------------------------------------------------
    + */
    +struct aic3262_setup_data {
    +	unsigned short i2c_address;
    +};
    +
    +/* GPIO API */
    +#define AIC3262_NUM_GPIO 5	/* include 2 GPI and 1 GPO pins */
    +enum {
    +	AIC3262_GPIO1_FUNC_DISABLED =		0,
    +	AIC3262_GPIO1_FUNC_INPUT =		1,
    +	AIC3262_GPIO1_FUNC_OUTPUT =		3,
    +	AIC3262_GPIO1_FUNC_CLOCK_OUTPUT =	4,
    +	AIC3262_GPIO1_FUNC_INT1_OUTPUT =	5,
    +	AIC3262_GPIO1_FUNC_INT2_OUTPUT =	6,
    +	AIC3285_GPIO_FUNC_DSD_CHAN1_OUTPUT = 	7,
    +	AIC3285_GPIO_FUNC_DSD_CHAN2_OUTPUT = 	8,
    +	AIC3285_GPIO_FUNC_DAC_MOD_CLK_OUTPUT = 	9,
    +	AIC3262_GPIO1_FUNC_ADC_MOD_CLK_OUTPUT =	10,
    +	AIC3262_GPIO1_FUNC_SAR_ADC_INTERRUPT =	12,
    +	AIC3262_GPIO1_FUNC_ASI1_DATA_OUTPUT =	15,
    +	AIC3262_GPIO1_FUNC_ASI1_WCLK =		16,
    +	AIC3262_GPIO1_FUNC_ASI1_BCLK =		17,
    +	AIC3262_GPIO1_FUNC_ASI2_WCLK =		18,
    +	AIC3262_GPIO1_FUNC_ASI2_BCLK =		19,
    +	AIC3262_GPIO1_FUNC_ASI3_WCLK =		20,
    +	AIC3262_GPIO1_FUNC_ASI3_BCLK =		21,
    +	AIC3285_GPIO_I2C_MASTER_SCL =		30,
    +	AIC3285_GPIO_I2C_MASTER_SDA =		30,
    +};
    +
    +enum {
    +	AIC3262_GPIO2_FUNC_DISABLED =		0,
    +	AIC3262_GPIO2_FUNC_INPUT =		1,
    +	AIC3262_GPIO2_FUNC_OUTPUT =		3,
    +	AIC3262_GPIO2_FUNC_CLOCK_OUTPUT =	4,
    +	AIC3262_GPIO2_FUNC_INT1_OUTPUT =	5,
    +	AIC3262_GPIO2_FUNC_INT2_OUTPUT =	6,
    +	AIC3262_GPIO2_FUNC_ADC_MOD_CLK_OUTPUT = 10,
    +	AIC3262_GPIO2_FUNC_SAR_ADC_INTERRUPT =	12,
    +	AIC3262_GPIO2_FUNC_ASI1_DATA_OUTPUT =	15,
    +	AIC3262_GPIO2_FUNC_ASI1_WCLK =		16,
    +	AIC3262_GPIO2_FUNC_ASI1_BCLK =		17,
    +	AIC3262_GPIO2_FUNC_ASI2_WCLK =		18,
    +	AIC3262_GPIO2_FUNC_ASI2_BCLK =		19,
    +	AIC3262_GPIO2_FUNC_ASI3_WCLK =		20,
    +	AIC3262_GPIO2_FUNC_ASI3_BCLK =		21
    +};
    +enum {
    +	AIC3262_GPO1_FUNC_DISABLED =		0,
    +	AIC3262_GPO1_FUNC_MSO_OUTPUT_FOR_SPI =	1,
    +	AIC3262_GPO1_FUNC_GENERAL_PURPOSE_OUTPUT = 2,
    +	AIC3262_GPO1_FUNC_CLOCK_OUTPUT =	3,
    +	AIC3262_GPO1_FUNC_INT1_OUTPUT =	4,
    +	AIC3262_GPO1_FUNC_INT2_OUTPUT =	5,
    +	AIC3262_GPO1_FUNC_ADC_MOD_CLK_OUTPUT =	7,
    +	AIC3262_GPO1_FUNC_SAR_ADC_INTERRUPT =	12,
    +	AIC3262_GPO1_FUNC_ASI1_DATA_OUTPUT =	15,
    +};
    +/*
    + *----------------------------------------------------------------------------
    + * @struct  aic3262_configs |
    + *          AIC3262 initialization data which has register offset and register
    + *          value.
    + * @field   u8 | book_no |
    + *          AIC3262 Book Number Offsets required for initialization..
    + * @field   u16 | reg_offset |
    + *          AIC3262 Register offsets required for initialization..
    + * @field   u8 | reg_val |
    + *          value to set the AIC3262 register to initialize the AIC3262.
    + *---------------------------------------------------------------------------
    + */
    +struct aic3xxx_configs {
    +	u8 book_no;
    +	u16 reg_offset;
    +	u8 reg_val;
    +};
    +
    +/*
    + *----------------------------------------------------------------------------
    + * @struct  aic3262_rate_divs |
    + *          Setting up the values to get different freqencies
    + *
    + * @field   u32 | mclk |
    + *          Master clock
    + * @field   u32 | rate |
    + *          sample rate
    + * @field   u8 | p_val |
    + *          value of p in PLL
    + * @field   u32 | pll_j |
    + *          value for pll_j
    + * @field   u32 | pll_d |
    + *          value for pll_d
    + * @field   u32 | dosr |
    + *          value to store dosr
    + * @field   u32 | ndac |
    + *          value for ndac
    + * @field   u32 | mdac |
    + *          value for mdac
    + * @field   u32 | aosr |
    + *          value for aosr
    + * @field   u32 | nadc |
    + *          value for nadc
    + * @field   u32 | madc |
    + *          value for madc
    + * @field   u32 | blck_N |
    + *          value for block N
    + */
    +struct aic3xxx {
    +	struct mutex io_lock;
    +	struct mutex irq_lock;
    +	enum aic3xxx_type type;
    +	struct device *dev;
    +	struct regmap *regmap;
    +	struct aic3xxx_pdata *pdata;
    +	void *control_data;
    +	unsigned int irq;
    +	unsigned int irq_base;
    +	u8 irq_masks_cur;
    +	u8 irq_masks_cache;
    +	/* Used over suspend/resume */
    +	bool suspended;
    +	u8 book_no;
    +	u8 page_no;
    +};
    +
    +struct aic3262_gpio_setup {
    +	u8 used;		/* GPIO, GPI and GPO is used in the board, */
    +				/* used = 1 else 0 */
    +	u8 in;			/* GPIO is used as input, in = 1 else in = 0 */
    +				/* GPI in = 1, GPO in = 0 */
    +	unsigned int in_reg;	/* if GPIO is input,
    +					register to write the mask. */
    +	u8 in_reg_bitmask;	/* bitmask for 'value' to be
    +					written into in_reg */
    +	u8 in_reg_shift;	/* bits to shift to write 'value'
    +					into in_reg */
    +	u8 value;		/* value to be written
    +					gpio_control_reg if GPIO */
    +				/* is output, in_reg if its input */
    +};
    +
    +struct aic3xxx_pdata {
    +	unsigned int audio_mclk1;
    +	unsigned int audio_mclk2;
    +	unsigned int gpio_irq;	/* whether AIC3262 interrupts the host AP on */
    +				/* a GPIO pin of AP */
    +	unsigned int gpio_reset;/* is the codec being reset by a gpio*/
    +				/* [host] pin, if yes provide the number. */
    +	struct aic3262_gpio_setup *gpio;/* all gpio configuration */
    +	int naudint_irq;	/* audio interrupt */
    +	unsigned int irq_base;
    +};
    +
    +static inline int aic3xxx_request_irq(struct aic3xxx *aic3xxx, int irq,
    +				      irq_handler_t handler,
    +				      unsigned long irqflags, const char *name,
    +				      void *data)
    +{
    +	if (!aic3xxx->irq_base)
    +		return -EINVAL;
    +
    +	return request_threaded_irq(aic3xxx->irq_base + irq, NULL, handler,
    +				    irqflags, name, data);
    +}
    +
    +static inline int aic3xxx_free_irq(struct aic3xxx *aic3xxx, int irq, void *data)
    +{
    +	if (!aic3xxx->irq_base)
    +		return -EINVAL;
    +
    +	free_irq(aic3xxx->irq_base + irq, data);
    +	return 0;
    +}
    +
    +/* Device I/O API */
    +int aic3xxx_reg_read(struct aic3xxx *aic3xxx, unsigned int reg);
    +int aic3xxx_reg_write(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      unsigned char val);
    +int aic3xxx_set_bits(struct aic3xxx *aic3xxx, unsigned int reg,
    +		     unsigned char mask, unsigned char val);
    +int aic3xxx_bulk_read(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      int count, u8 *buf);
    +int aic3xxx_bulk_write(struct aic3xxx *aic3xxx, unsigned int reg,
    +		       int count, const u8 *buf);
    +int aic3xxx_wait_bits(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      unsigned char mask, unsigned char val, int delay,
    +		      int counter);
    +
    +int aic3xxx_irq_init(struct aic3xxx *aic3xxx);
    +void aic3xxx_irq_exit(struct aic3xxx *aic3xxx);
    +int aic3xxx_device_init(struct aic3xxx *aic3xxx, int irq);
    +void aic3xxx_device_exit(struct aic3xxx *aic3xxx);
    +
    +#endif /* End of __MFD_AIC3262_CORE_H__ */
    diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
    index 41f8ca215..228984248 100644
    --- a/sound/soc/codecs/Kconfig
    +++ b/sound/soc/codecs/Kconfig
    @@ -287,6 +287,7 @@ config SND_SOC_ALL_CODECS
     	imply SND_SOC_TLV320AIC32X4_SPI
     	imply SND_SOC_TLV320AIC3X_I2C
     	imply SND_SOC_TLV320AIC3X_SPI
    +	imply SND_SOC_AIC3262
     	imply SND_SOC_TPA6130A2
     	imply SND_SOC_TLV320DAC33
     	imply SND_SOC_TSCS42XX
    @@ -2213,6 +2214,13 @@ config SND_SOC_TLV320ADCX140
     	  Add support for Texas Instruments tlv320adc3140, tlv320adc5140 and
     	  tlv320adc6140 quad channel ADCs.
     
    +config SND_SOC_AIC3262
    +	tristate "Texas Instrument TLV320AIC3262 CODEC chip"
    +	depends on I2C
    +	select REGMAP_I2C
    +	help
    +	  add codec driver for tlv320aic3262
    +
     config SND_SOC_TS3A227E
     	tristate "TI Headset/Mic detect and keypress chip"
     	depends on I2C
    diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
    index b56d49b30..e9c631964 100644
    --- a/sound/soc/codecs/Makefile
    +++ b/sound/soc/codecs/Makefile
    @@ -331,6 +331,7 @@ snd-soc-tlv320aic3x-i2c-y := tlv320aic3x-i2c.o
     snd-soc-tlv320aic3x-spi-y := tlv320aic3x-spi.o
     snd-soc-tlv320dac33-y := tlv320dac33.o
     snd-soc-tlv320adcx140-y := tlv320adcx140.o
    +snd-soc-tlv320aic3262-objs := tlv320aic326x.o aic3xxx/aic3xxx_cfw_ops.o
     snd-soc-tscs42xx-y := tscs42xx.o
     snd-soc-tscs454-y := tscs454.o
     snd-soc-ts3a227e-y := ts3a227e.o
    @@ -754,6 +755,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC3X_I2C)	+= snd-soc-tlv320aic3x-i2c.o
     obj-$(CONFIG_SND_SOC_TLV320AIC3X_SPI)	+= snd-soc-tlv320aic3x-spi.o
     obj-$(CONFIG_SND_SOC_TLV320DAC33)	+= snd-soc-tlv320dac33.o
     obj-$(CONFIG_SND_SOC_TLV320ADCX140)	+= snd-soc-tlv320adcx140.o
    +obj-$(CONFIG_SND_SOC_AIC3262)	+= snd-soc-tlv320aic3262.o
     obj-$(CONFIG_SND_SOC_TSCS42XX)	+= snd-soc-tscs42xx.o
     obj-$(CONFIG_SND_SOC_TSCS454)	+= snd-soc-tscs454.o
     obj-$(CONFIG_SND_SOC_TS3A227E)	+= snd-soc-ts3a227e.o
    diff --git a/sound/soc/codecs/aic3xxx/aic3xxx_cfw.h b/sound/soc/codecs/aic3xxx/aic3xxx_cfw.h
    new file mode 100644
    index 000000000..2012d510f
    --- /dev/null
    +++ b/sound/soc/codecs/aic3xxx/aic3xxx_cfw.h
    @@ -0,0 +1,529 @@
    +/*
    + *  aic3xxx_cfw.h  --  SoC audio for TI OMAP44XX SDP
    + *                      Codec Firmware Declarations
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#ifndef CFW_FIRMWARE_H_
    +#define CFW_FIRMWARE_H_
    +
    +
    +#define CFW_FW_MAGIC 0xC0D1F1ED
    +
    +
    +/** \defgroup pd Arbitrary Limitations */
    +/* @{ */
    +#ifndef CFW_MAX_ID
    +#    define CFW_MAX_ID          (64)	/**<Max length of string identifies*/
    +#    define CFW_MAX_VARS       (256)	/**<Number of "variables" alive at the*/
    +					/**<same time in an acx file*/
    +#endif
    +
    +/* @} */
    +
    +
    +
    +/** \defgroup st Enums, Flags, Macros and Supporting Types */
    +/* @{ */
    +
    +
    +/**
    + * Device Family Identifier
    + *
    + */
    +enum __attribute__ ((__packed__)) cfw_dfamily {
    +	CFW_DFM_TYPE_A,
    +	CFW_DFM_TYPE_B,
    +	CFW_DFM_TYPE_C
    +};
    +
    +/**
    + * Device Identifier
    + *
    + */
    +enum __attribute__ ((__packed__)) cfw_device {
    +	CFW_DEV_DAC3120,
    +	CFW_DEV_DAC3100,
    +	CFW_DEV_AIC3120,
    +	CFW_DEV_AIC3100,
    +	CFW_DEV_AIC3110,
    +	CFW_DEV_AIC3111,
    +	CFW_DEV_AIC36,
    +	CFW_DEV_AIC3206,
    +	CFW_DEV_AIC3204,
    +	CFW_DEV_AIC3254,
    +	CFW_DEV_AIC3256,
    +	CFW_DEV_AIC3253,
    +	CFW_DEV_AIC3212,
    +	CFW_DEV_AIC3262,
    +	CFW_DEV_AIC3017,
    +	CFW_DEV_AIC3008,
    +
    +	CFW_DEV_AIC3266,
    +	CFW_DEV_AIC3285,
    +};
    +
    +/**
    + * Transition Sequence Identifier
    + *
    + */
    +enum cfw_transition_t {
    +	CFW_TRN_INIT,
    +	CFW_TRN_RESUME,
    +	CFW_TRN_NEUTRAL,
    +	CFW_TRN_A_MUTE,
    +	CFW_TRN_D_MUTE,
    +	CFW_TRN_AD_MUTE,
    +	CFW_TRN_A_UNMUTE,
    +	CFW_TRN_D_UNMUTE,
    +	CFW_TRN_AD_UNMUTE,
    +	CFW_TRN_SUSPEND,
    +	CFW_TRN_EXIT,
    +	CFW_TRN_N
    +};
    +
    +#ifndef __cplusplus
    +static const char *const cfw_transition_id[] = {
    +	[CFW_TRN_INIT]     "INIT",
    +	[CFW_TRN_RESUME]   "RESUME",
    +	[CFW_TRN_NEUTRAL]  "NEUTRAL",
    +	[CFW_TRN_A_MUTE]   "A_MUTE",
    +	[CFW_TRN_D_MUTE]   "D_MUTE",
    +	[CFW_TRN_AD_MUTE]  "AD_MUTE",
    +	[CFW_TRN_A_UNMUTE] "A_UNMUTE",
    +	[CFW_TRN_D_UNMUTE] "D_UNMUTE",
    +	[CFW_TRN_AD_UNMUTE]"AD_UNMUTE",
    +	[CFW_TRN_SUSPEND]  "SUSPEND",
    +	[CFW_TRN_EXIT]     "EXIT",
    +};
    +#endif
    +
    +/* @} */
    +
    +/** \defgroup ds Data Structures */
    +/* @{ */
    +
    +
    +/**
    +* CFW Command
    +* These commands do not appear in the register
    +* set of the device.
    +*/
    +enum __attribute__ ((__packed__)) cfw_cmd_id {
    +	CFW_CMD_NOP = 0x80,
    +	CFW_CMD_DELAY,
    +	CFW_CMD_UPDTBITS,
    +	CFW_CMD_WAITBITS,
    +	CFW_CMD_LOCK,
    +	CFW_CMD_BURST,
    +	CFW_CMD_RBURST,
    +	CFW_CMD_LOAD_VAR_IM,
    +	CFW_CMD_LOAD_VAR_ID,
    +	CFW_CMD_STORE_VAR,
    +	CFW_CMD_COND,
    +	CFW_CMD_BRANCH,
    +	CFW_CMD_BRANCH_IM,
    +	CFW_CMD_BRANCH_ID,
    +	CFW_CMD_PRINT,
    +	CFW_CMD_OP_ADD = 0xC0,
    +	CFW_CMD_OP_SUB,
    +	CFW_CMD_OP_MUL,
    +	CFW_CMD_OP_DIV,
    +	CFW_CMD_OP_AND,
    +	CFW_CMD_OP_OR,
    +	CFW_CMD_OP_SHL,
    +	CFW_CMD_OP_SHR,
    +	CFW_CMD_OP_RR,
    +	CFW_CMD_OP_XOR,
    +	CFW_CMD_OP_NOT,
    +	CFW_CMD_OP_LNOT,
    +};
    +
    +/**
    +* CFW Delay
    +* Used for the cmd command delay
    +* Has one parameter of delay time in ms
    +*/
    +struct cfw_cmd_delay {
    +	u16 delay;
    +	enum cfw_cmd_id cid;
    +	u8 delay_fine;
    +};
    +
    +/**
    +* CFW Lock
    +* Take codec mutex to avoid clashing with DAPM operations
    +*/
    +struct cfw_cmd_lock {
    +	u16 lock;
    +	enum cfw_cmd_id cid;
    +	u8 unused;
    +};
    +
    +
    +/**
    + * CFW  UPDTBITS, WAITBITS, CHKBITS
    + * Both these cmd commands have same arguments
    + * cid will be used to specify which command it is
    + * has parameters of book, page, offset and mask
    + */
    +struct cfw_cmd_bitop {
    +	u16 unused1;
    +	enum cfw_cmd_id cid;
    +	u8 mask;
    +};
    +
    +/**
    + * CFW  CMD Burst header
    + * Burst writes inside command array
    + * Followed by burst address, first byte
    + */
    +struct cfw_cmd_bhdr {
    +	u16 len;
    +	enum cfw_cmd_id cid;
    +	u8 unused;
    +};
    +
    +/**
    + * CFW  CMD Burst
    + * Burst writes inside command array
    + * Followed by data to the extent indicated in previous len
    + * Can be safely cast to cfw_burst
    + */
    +struct cfw_cmd_burst {
    +	u8 book;
    +	u8 page;
    +	u8 offset;
    +	u8 data[1];
    +};
    +#define CFW_CMD_BURST_LEN(n) (2 + ((n) - 1 + 3)/4)
    +
    +/**
    + * CFW  CMD Scratch register
    + * For load
    + *  if (svar != dvar)
    + *      dvar = setbits(svar, mask) // Ignore reg
    + *  else
    + *      dvar = setbits(reg, mask)
    + * For store
    + *  if (svar != dvar)
    + *      reg = setbits(svar,  dvar)
    + *  else
    + *      reg =  setbits(svar, mask)
    + *
    + */
    +struct cfw_cmd_ldst {
    +	u8 dvar;
    +	u8 svar;
    +	enum cfw_cmd_id cid;
    +	u8 mask;
    +};
    +
    +/**
    + * CFW  CMD Conditional
    + * May only precede branch. Followed by nmatch+1 jump
    + * instructions
    + *   cond = svar&mask
    + * At each of the following nmatch+1 branch command
    + *   if (cond == match)
    + *       take the branch
    + */
    +struct cfw_cmd_cond {
    +	u8 svar;
    +	u8 nmatch;
    +	enum cfw_cmd_id cid;
    +	u8 mask;
    +};
    +#define CFW_CMD_COND_LEN(nm) (1 + ((nm)+1))
    +
    +/**
    + * CFW  CMD Goto
    + * For branch, break, continue and stop
    + */
    +struct cfw_cmd_branch {
    +	u16 address;
    +	enum cfw_cmd_id cid;
    +	u8 match;
    +};
    +
    +/**
    + * CFW  Debug print
    + * For diagnostics
    + */
    +struct cfw_cmd_print {
    +	u8 fmtlen;
    +	u8 nargs;
    +	enum cfw_cmd_id cid;
    +	char fmt[1];
    +};
    +
    +#define CFW_CMD_PRINT_LEN(p) (1 + ((p).fmtlen/4) + (((p).nargs + 3)/4))
    +#define CFW_CMD_PRINT_ARG(p) (1 + ((p).fmtlen/4))
    +
    +/**
    + * CFW  Arithmetic and logical operations
    + *  Bit 5 indicates if op1 is indirect
    + *  Bit 6 indicates if op2 is indirect
    + */
    +struct cfw_cmd_op {
    +	u8 op1;
    +	u8 op2;
    +	enum cfw_cmd_id cid;
    +	u8 dst;
    +};
    +#define CFW_CMD_OP1_ID     (1u<<5)
    +#define CFW_CMD_OP2_ID     (1u<<4)
    +
    +#define CFW_CMD_OP_START   CFW_CMD_OP_ADD
    +#define CFW_CMD_OP_END     (CFW_CMD_OP_LNOT|CFW_CMD_OP1_ID|CFW_CMD_OP2_ID)
    +#define CFW_CMD_OP_IS_UNARY(x) \
    +			(((x) == CFW_CMD_OP_NOT) || ((x) == CFW_CMD_OP_LNOT))
    +
    +
    +/**
    + * CFW Register
    + *
    + * A single reg write
    + *
    + */
    +union cfw_register {
    +	struct {
    +		u8 book;
    +		u8 page;
    +		u8 offset;
    +		u8 data;
    +	};
    +	u32 bpod;
    +};
    +
    +
    +
    +/**
    + * CFW Command
    + *
    + * Can be a either a
    + *      -# single register write, or
    + *      -# command
    + *
    + */
    +union cfw_cmd {
    +	struct {
    +		u16 unused1;
    +		enum cfw_cmd_id cid;
    +		u8 unused2;
    +	};
    +	union cfw_register reg;
    +	struct cfw_cmd_delay delay;
    +	struct cfw_cmd_lock lock;
    +	struct cfw_cmd_bitop bitop;
    +	struct cfw_cmd_bhdr bhdr;
    +	struct cfw_cmd_burst burst;
    +	struct cfw_cmd_ldst ldst;
    +	struct cfw_cmd_cond cond;
    +	struct cfw_cmd_branch branch;
    +	struct cfw_cmd_print print;
    +	u8     print_arg[4];
    +	struct cfw_cmd_op op;
    +};
    +
    +#define CFW_REG_IS_CMD(x) ((x).cid >= CFW_CMD_DELAY)
    +
    +/**
    + * CFW Block Type
    + *
    + * Block identifier
    + *
    + */
    +enum __attribute__ ((__packed__)) cfw_block_t {
    +	CFW_BLOCK_SYSTEM_PRE,
    +	CFW_BLOCK_A_INST,
    +	CFW_BLOCK_A_A_COEF,
    +	CFW_BLOCK_A_B_COEF,
    +	CFW_BLOCK_A_F_COEF,
    +	CFW_BLOCK_D_INST,
    +	CFW_BLOCK_D_A1_COEF,
    +	CFW_BLOCK_D_B1_COEF,
    +	CFW_BLOCK_D_A2_COEF,
    +	CFW_BLOCK_D_B2_COEF,
    +	CFW_BLOCK_D_F_COEF,
    +	CFW_BLOCK_SYSTEM_POST,
    +	CFW_BLOCK_N,
    +	CFW_BLOCK_INVALID,
    +};
    +#define CFW_BLOCK_D_A_COEF CFW_BLOCK_D_A1_COEF
    +#define CFW_BLOCK_D_B_COEF CFW_BLOCK_D_B1_COEF
    +
    +/**
    + * CFW Block
    + *
    + * A block of logically grouped sequences/commands/cmd-commands
    + *
    + */
    +struct cfw_block {
    +	enum cfw_block_t type;
    +	int ncmds;
    +	union cfw_cmd cmd[];
    +};
    +#define CFW_BLOCK_SIZE(ncmds) (sizeof(struct cfw_block) + \
    +				((ncmds)*sizeof(union cfw_cmd)))
    +
    +/**
    + * CFW Image
    + *
    + * A downloadable image
    + */
    +struct cfw_image {
    +	char name[CFW_MAX_ID];	/**< Name of the pfw/overlay/configuration*/
    +	char *desc;		/**< User string*/
    +	int mute_flags;
    +	struct cfw_block *block[CFW_BLOCK_N];
    +};
    +
    +
    +
    +/**
    + * CFW PLL
    + *
    + * PLL configuration sequence and match critirea
    + */
    +struct cfw_pll {
    +	char name[CFW_MAX_ID];	/**< Name of the PLL sequence*/
    +	char *desc;		/**< User string*/
    +	struct cfw_block *seq;
    +};
    +
    +/**
    + * CFW Control
    + *
    + * Run-time control for a process flow
    + */
    +struct cfw_control {
    +	char name[CFW_MAX_ID];	/**< Control identifier*/
    +	char *desc;		/**< User string*/
    +	int mute_flags;
    +
    +	int min;		/**< Min value of control (*100)*/
    +	int max;		/**< Max  value of control (*100)*/
    +	int step;		/**< Control step size (*100)*/
    +
    +	int imax;		/**< Max index into controls array*/
    +	int ireset;		/**< Reset control to defaults*/
    +	int icur;		/**< Last value set*/
    +	struct cfw_block **output;	/**< Array of sequences to send*/
    +};
    +
    +/**
    + * Process flow
    + *
    + * Complete description of a process flow
    + */
    +struct cfw_pfw {
    +	char name[CFW_MAX_ID];	/**< Name of the process flow*/
    +	char *desc;		/**< User string*/
    +	u32 version;
    +	u8 prb_a;
    +	u8 prb_d;
    +	int novly;		/**< Number of overlays (1 or more)*/
    +	int ncfg;		/**< Number of configurations (0 or more)*/
    +	int nctrl;		/**< Number of run-time controls*/
    +	struct cfw_image *base;	/**< Base sequence*/
    +	struct cfw_image **ovly_cfg;	/**< Overlay and cfg*/
    +					/**< patches (if any)*/
    +	struct cfw_control **ctrl;	/**< Array of run-time controls*/
    +};
    +
    +#define CFW_OCFG_NDX(p, o, c) (((o)*(p)->ncfg)+(c))
    +/**
    + * Process transition
    + *
    + * Sequence for specific state transisitions within the driver
    + *
    + */
    +struct cfw_transition {
    +	char name[CFW_MAX_ID];	/**< Name of the transition*/
    +	char *desc;		/**< User string*/
    +	struct cfw_block *block;
    +};
    +
    +/**
    + * Device audio mode
    + *
    + * Link operating modes to process flows,
    + * configurations and sequences
    + *
    + */
    +struct cfw_mode {
    +	char name[CFW_MAX_ID];
    +	char *desc;		/**< User string*/
    +	u32 flags;
    +	u8 pfw;
    +	u8 ovly;
    +	u8 cfg;
    +	u8 pll;
    +	struct cfw_block *entry;
    +	struct cfw_block *exit;
    +};
    +
    +struct cfw_asoc_toc_entry {
    +	char etext[CFW_MAX_ID];
    +	int mode;
    +	int cfg;
    +};
    +
    +struct cfw_asoc_toc {
    +	int nentries;
    +	struct cfw_asoc_toc_entry entry[];
    +};
    +
    +/**
    + * CFW Project
    + *
    + * Top level structure describing the CFW project
    + */
    +struct cfw_project {
    +	u32 magic;		/**< magic number for identifying F/W file*/
    +	u32 if_id;		/**< Interface match code */
    +	u32 size;		/**< Total size of the firmware (including this header)*/
    +	u32 cksum;		/**< CRC32 of the pickled firmware */
    +	u32 version;		/**< Firmware version (from CFD file)*/
    +	u32 tstamp;		/**< Time stamp of firmware build (epoch seconds)*/
    +	char name[CFW_MAX_ID];	/**< Project name*/
    +	char *desc;		/**< User string*/
    +	enum cfw_dfamily dfamily;	/**< Device family*/
    +	enum cfw_device device;	/**< Device identifier*/
    +	u32 flags;		/**< CFW flags*/
    +
    +	struct cfw_transition **transition;	/**< Transition sequences*/
    +
    +	u16 npll;		/**< Number of PLL settings*/
    +	struct cfw_pll **pll;	/**< PLL settings*/
    +
    +	u16 npfw;		/**< Number of process flows*/
    +	struct cfw_pfw **pfw;	/**< Process flows*/
    +
    +	u16 nmode;		/**< Number of operating modes*/
    +	struct cfw_mode **mode;	/**< Modes*/
    +
    +	struct cfw_asoc_toc *asoc_toc;	/**< list of amixer controls*/
    +};
    +
    +
    +/* @} */
    +
    +/* **CFW_INTERFACE_ID=0x3FA6D547** */
    +
    +#endif				/* CFW_FIRMWARE_H_ */
    diff --git a/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c b/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c
    new file mode 100644
    index 000000000..62b57870c
    --- /dev/null
    +++ b/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c
    @@ -0,0 +1,1134 @@
    +/*
    + * linux/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c
    + *
    + * Copyright (C) 2011 Texas Instruments Inc.,
    + *
    + * This package is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2 as
    + * published by the Free Software Foundation.
    + *
    + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
    + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    + *
    + */
    +
    +#include <linux/module.h>
    +#include <linux/delay.h>
    +#include <sound/pcm.h>
    +#include <sound/pcm_params.h>
    +#include <sound/soc.h>
    +#include <linux/slab.h>
    +#include <sound/tlv.h>
    +
    +/* FIXME to be removed/replaced */
    +#define warn(fmt, ...)	printk(fmt "\n", ##__VA_ARGS__)
    +#define error(fmt, ...)	printk(fmt "\n", ##__VA_ARGS__)
    +#define DBG printk
    +
    +#include "aic3xxx_cfw.h"
    +#include "aic3xxx_cfw_ops.h"
    +
    +
    +/* **Code beyond this point is compilable on host** */
    +
    +/*
    + * Firmware version numbers are used to make sure that the
    + * host and target code stay in sync.  It is _not_ recommended
    + * to provide this number from the outside (E.g., from a makefile)
    + * Instead, a set of automated tools are relied upon to keep the numbers
    + * in sync at the time of host testing.
    + */
    +#undef CFW_FW_IF_ID
    +#define CFW_FW_IF_ID 0x3FA6D547
    +static int aic3xxx_cfw_dlimage(struct cfw_state *ps, struct cfw_image *pim);
    +static int aic3xxx_cfw_dlcfg(struct cfw_state *ps, struct cfw_image *pim);
    +static int aic3xxx_cfw_dlctl(struct cfw_state *ps, struct cfw_block *pb,
    +			     u32 mute_flags);
    +
    +static void aic3xxx_cfw_dlcmds(struct cfw_state *ps, struct cfw_block *pb);
    +static int aic3xxx_cfw_set_mode_id(struct cfw_state *ps);
    +static int aic3xxx_cfw_mute(struct cfw_state *ps, int mute, u32 flags);
    +static int aic3xxx_cfw_setmode_cfg_u(struct cfw_state *ps, int mode, int cfg);
    +static int aic3xxx_cfw_setcfg_u(struct cfw_state *ps, int cfg);
    +static int aic3xxx_cfw_transition_u(struct cfw_state *ps, char *ttype);
    +static int aic3xxx_cfw_set_pll_u(struct cfw_state *ps, int asi);
    +static int aic3xxx_cfw_control_u(struct cfw_state *ps, char *cname, int param);
    +static struct cfw_project *aic3xxx_cfw_unpickle(void *pcfw, int n);
    +
    +static void aic3xxx_wait(struct cfw_state *ps, unsigned int reg, u8 mask,
    +			 u8 data);
    +static void aic3xxx_set_bits(u8 *data, u8 mask, u8 val);
    +static int aic3xxx_driver_init(struct cfw_state *ps);
    +
    +int aic3xxx_cfw_init(struct cfw_state *ps, const struct aic3xxx_codec_ops *ops,
    +		     struct snd_soc_component *codec)
    +{
    +	ps->ops = ops;
    +	ps->codec = codec;
    +	ps->pjt = NULL;
    +	mutex_init(&ps->mutex);
    +
    +	/* FIXME Need a special CONFIG flag to disable debug driver */
    +	aic3xxx_driver_init(ps);
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_lock(struct cfw_state *ps, int lock)
    +{
    +	if (lock)
    +		mutex_lock(&ps->mutex);
    +	else
    +		mutex_unlock(&ps->mutex);
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_reload(struct cfw_state *ps, void *pcfw, int n)
    +{
    +	ps->pjt = aic3xxx_cfw_unpickle(pcfw, n);
    +	ps->cur_mode_id =
    +	    ps->cur_mode = ps->cur_pll = ps->cur_pfw =
    +	    ps->cur_ovly = ps->cur_cfg = -1;
    +	if (ps->pjt == NULL)
    +		return -1;
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_setmode(struct cfw_state *ps, int mode)
    +{
    +	struct cfw_project *pjt;
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	pjt = ps->pjt;
    +	if (pjt == NULL) {
    +		aic3xxx_cfw_lock(ps, 0);
    +		return -1;
    +	}
    +	ret = aic3xxx_cfw_setmode_cfg_u(ps, mode, pjt->mode[mode]->cfg);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +int aic3xxx_cfw_setcfg(struct cfw_state *ps, int cfg)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_setcfg_u(ps, cfg);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_setcfg_u(struct cfw_state *ps, int cfg)
    +{
    +	struct cfw_project *pjt = ps->pjt;
    +	struct cfw_pfw *pfw;
    +	struct cfw_image *patch;
    +
    +	if (pjt == NULL)
    +		return -1;
    +	if (ps->cur_pfw < 0 || ps->cur_pfw >= pjt->npfw)
    +		return -1;	/* Non miniDSP */
    +	if (ps->cur_cfg == cfg)
    +		return 0;
    +	pfw = pjt->pfw[ps->cur_pfw];
    +	if (pfw->ncfg == 0 && cfg != 0)
    +		return -1;
    +	if (cfg > 0 && cfg >= pfw->ncfg)
    +		return -1;
    +	ps->cur_cfg = cfg;
    +	aic3xxx_cfw_set_mode_id(ps);
    +	patch =
    +	    pfw->ovly_cfg[CFW_OCFG_NDX(pfw, ps->cur_ovly, ps->cur_cfg)];
    +	if (pfw->ncfg != 0)
    +		return aic3xxx_cfw_dlcfg(ps, patch);
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_setmode_cfg(struct cfw_state *ps, int mode, int cfg)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_setmode_cfg_u(ps, mode, cfg);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_setmode_cfg_u(struct cfw_state *ps, int mode, int cfg)
    +{
    +	struct cfw_project *pjt = ps->pjt;
    +	struct cfw_mode *pmode;
    +	int which = 0, ocndx;
    +
    +	if (pjt == NULL)
    +		goto err;
    +	if ((mode < 0) || (mode >= pjt->nmode))
    +		goto err;
    +	if (cfg < 0)
    +		goto err;
    +	if (mode == ps->cur_mode)
    +		return aic3xxx_cfw_setcfg_u(ps, cfg);
    +
    +	/* Apply exit sequence for previous mode if present */
    +	if (ps->cur_mode >= 0)
    +		aic3xxx_cfw_dlcmds(ps, pjt->mode[ps->cur_mode]->exit);
    +	pmode = pjt->mode[mode];
    +	if (pjt->mode[mode]->pfw < pjt->npfw) { /* New mode uses miniDSP */
    +		struct cfw_image *im;
    +		struct cfw_pfw *pfw = pjt->pfw[pmode->pfw];
    +
    +		/* Make sure cfg is valid and supported in this mode */
    +		if (pfw->ncfg == 0 && cfg != 0)
    +			goto err;
    +		if (cfg > 0 && cfg >= pfw->ncfg)
    +			goto err;
    +
    +		/*
    +		 * Decisions about which miniDSP to stop/restart are taken
    +		 * on the basis of sections present in the _base_ image
    +		 * This allows for correct sync mode operation even in cases
    +		 * where the base PFW uses both miniDSPs where a particular
    +		 * overlay applies only to one
    +		 */
    +		im = pfw->base;
    +		if (im->block[CFW_BLOCK_A_INST])
    +			which |= AIC3XXX_COPS_MDSP_A;
    +		if (im->block[CFW_BLOCK_D_INST])
    +			which |= AIC3XXX_COPS_MDSP_D;
    +
    +		if (pmode->pfw != ps->cur_pfw) {
    +
    +			/* New mode requires different PFW */
    +			ps->cur_pfw = pmode->pfw;
    +			ps->cur_ovly = 0;
    +			ps->cur_cfg = 0;
    +
    +			which = ps->ops->stop(ps->codec, which);
    +			aic3xxx_cfw_dlimage(ps, im);
    +			if (pmode->ovly && pmode->ovly < pfw->novly) {
    +
    +				/* New mode uses ovly */
    +				ocndx = CFW_OCFG_NDX(pfw, pmode->ovly, cfg);
    +				aic3xxx_cfw_dlimage(ps,
    +						    pfw->ovly_cfg[ocndx]);
    +			} else if (pfw->ncfg > 0) {
    +
    +				/* new mode needs only a cfg change */
    +				ocndx = CFW_OCFG_NDX(pfw, 0, cfg);
    +				aic3xxx_cfw_dlimage(ps,
    +						    pfw->ovly_cfg[ocndx]);
    +			}
    +			ps->ops->restore(ps->codec, which);
    +
    +		} else if (pmode->ovly != ps->cur_ovly) {
    +
    +			/* New mode requires only an ovly change */
    +			ocndx = CFW_OCFG_NDX(pfw, pmode->ovly, cfg);
    +			which = ps->ops->stop(ps->codec, which);
    +			aic3xxx_cfw_dlimage(ps, pfw->ovly_cfg[ocndx]);
    +			ps->ops->restore(ps->codec, which);
    +		} else if (pfw->ncfg > 0 && cfg != ps->cur_cfg) {
    +
    +			/* New mode requires only a cfg change */
    +			ocndx = CFW_OCFG_NDX(pfw, pmode->ovly, cfg);
    +			aic3xxx_cfw_dlcfg(ps, pfw->ovly_cfg[ocndx]);
    +		}
    +		ps->cur_ovly = pmode->ovly;
    +		ps->cur_cfg = cfg;
    +
    +		ps->cur_mode = mode;
    +		aic3xxx_cfw_set_pll_u(ps, 0);
    +
    +	} else if (pjt->mode[mode]->pfw != 0xFF) {
    +
    +		/* Not bypass mode */
    +		warn("Bad pfw setting detected (%d).  Max pfw=%d",
    +		     pmode->pfw, pjt->npfw);
    +	}
    +	ps->cur_mode = mode;
    +	aic3xxx_cfw_set_mode_id(ps);
    +
    +	/* Transition to netural mode */
    +	aic3xxx_cfw_transition_u(ps, "NEUTRAL");
    +
    +	/* Apply entry sequence if present */
    +	aic3xxx_cfw_dlcmds(ps, pmode->entry);
    +
    +	DBG("setmode_cfg: DONE (mode=%d pfw=%d ovly=%d cfg=%d)",
    +	    ps->cur_mode, ps->cur_pfw, ps->cur_ovly, ps->cur_cfg);
    +	return 0;
    +
    +err:
    +	DBG("Failed to set firmware mode");
    +	return -EINVAL;
    +}
    +
    +int aic3xxx_cfw_transition(struct cfw_state *ps, char *ttype)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_transition_u(ps, ttype);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_transition_u(struct cfw_state *ps, char *ttype)
    +{
    +	int i;
    +
    +	if (ps->pjt == NULL)
    +		return -EINVAL;
    +	for (i = 0; i < CFW_TRN_N; ++i) {
    +		if (!strcasecmp(ttype, cfw_transition_id[i])) {
    +			struct cfw_transition *pt = ps->pjt->transition[i];
    +			DBG("Sending transition %s[%d]", ttype, i);
    +			if (pt)
    +				aic3xxx_cfw_dlcmds(ps, pt->block);
    +			return 0;
    +		}
    +	}
    +	warn("Transition %s not present or invalid", ttype);
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_set_pll(struct cfw_state *ps, int asi)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_set_pll_u(ps, asi);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_set_pll_u(struct cfw_state *ps, int asi)
    +{
    +	struct cfw_project *pjt = ps->pjt;
    +	int pll_id;
    +
    +	if (pjt == NULL)
    +		return -EINVAL;
    +	if (ps->cur_mode < 0)
    +		return -EINVAL;
    +	pll_id = pjt->mode[ps->cur_mode]->pll;
    +	if (ps->cur_pll != pll_id) {
    +		DBG("Re-configuring PLL: %s==>%d", pjt->pll[pll_id]->name,
    +		    pll_id);
    +		aic3xxx_cfw_dlcmds(ps, pjt->pll[pll_id]->seq);
    +		ps->cur_pll = pll_id;
    +	}
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_control(struct cfw_state *ps, char *cname, int param)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_control_u(ps, cname, param);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_control_u(struct cfw_state *ps, char *cname, int param)
    +{
    +	struct cfw_pfw *pfw;
    +	int i;
    +
    +	if (ps->cur_pfw < 0 || ps->cur_pfw >= ps->pjt->npfw) {
    +		warn("Not in MiniDSP mode");
    +		return 0;
    +	}
    +	pfw = ps->pjt->pfw[ps->cur_pfw];
    +	for (i = 0; i < pfw->nctrl; ++i) {
    +		struct cfw_control *pc = pfw->ctrl[i];
    +		if (strcasecmp(cname, pfw->ctrl[i]->name))
    +			continue;
    +		if (param < 0 || param > pc->imax) {
    +			warn("Parameter out of range\n");
    +			return -EINVAL;
    +		}
    +		DBG("Sending control %s[%d]", cname, param);
    +		pc->icur = param;
    +		aic3xxx_cfw_dlctl(ps, pc->output[param], pc->mute_flags);
    +		return 0;
    +	}
    +	warn("Control named %s not found in pfw %s", cname, pfw->name);
    +
    +	return -EINVAL;
    +}
    +
    +static void aic3xxx_cfw_op(struct cfw_state *ps, unsigned char *var,
    +			   struct cfw_cmd_op cmd)
    +{
    +	u32 op1, op2;
    +	u32 cid = cmd.cid;
    +
    +	op1 = cmd.op1;
    +	op2 = cmd.op2;
    +	if (cid & CFW_CMD_OP1_ID)
    +		op1 = var[op1];
    +	if (cid & CFW_CMD_OP2_ID)
    +		op2 = var[op2];
    +	cid &= ~(CFW_CMD_OP1_ID | CFW_CMD_OP2_ID);
    +
    +	switch (cid) {
    +	case CFW_CMD_OP_ADD:
    +		var[cmd.dst] = op1 + op2;
    +		break;
    +	case CFW_CMD_OP_SUB:
    +		var[cmd.dst] = op1 - op2;
    +		break;
    +	case CFW_CMD_OP_MUL:
    +		var[cmd.dst] = op1 * op2;
    +		break;
    +	case CFW_CMD_OP_DIV:
    +		var[cmd.dst] = op1 / op2;
    +		break;
    +	case CFW_CMD_OP_AND:
    +		var[cmd.dst] = op1 & op2;
    +		break;
    +	case CFW_CMD_OP_OR:
    +		var[cmd.dst] = op1 | op2;
    +		break;
    +	case CFW_CMD_OP_SHL:
    +		var[cmd.dst] = (op1 << op2);
    +		break;
    +	case CFW_CMD_OP_SHR:
    +		var[cmd.dst] = (op1 >> op2);
    +		break;
    +	case CFW_CMD_OP_RR:
    +		while (op2--)
    +			var[cmd.dst] = (op1 >> 1) | ((op1 & 1) << 7);
    +		break;
    +	case CFW_CMD_OP_XOR:
    +		var[cmd.dst] = op1 ^ op2;
    +		break;
    +	case CFW_CMD_OP_NOT:
    +		var[cmd.dst] = ~op1;
    +		break;
    +	case CFW_CMD_OP_LNOT:
    +		var[cmd.dst] = !op1;
    +		break;
    +	default:
    +		break;
    +	}
    +}
    +
    +static void aic3xxx_cfw_dlcmds(struct cfw_state *ps, struct cfw_block *pb)
    +{
    +	int pc = 0, cond = 0;
    +	unsigned char var[256];
    +
    +	if (!pb)
    +		return;
    +	while (pc < pb->ncmds) {
    +		union cfw_cmd *c = &(pb->cmd[pc]);
    +		if (c->cid != CFW_CMD_BRANCH_IM &&
    +		    c->cid != CFW_CMD_BRANCH_ID && c->cid != CFW_CMD_NOP)
    +			cond = 0;
    +		switch (c->cid) {
    +		case 0 ... (CFW_CMD_NOP - 1):
    +			ps->ops->reg_write(ps->codec, c->reg.bpod,
    +					   c->reg.data);
    +			pc += 1;
    +			break;
    +		case CFW_CMD_NOP:
    +			pc += 1;
    +			break;
    +		case CFW_CMD_DELAY:
    +			mdelay(c->delay.delay);
    +			pc += 1;
    +			break;
    +		case CFW_CMD_UPDTBITS:
    +			ps->ops->set_bits(ps->codec, c[1].reg.bpod,
    +					  c->bitop.mask, c[1].reg.data);
    +			pc += 2;
    +			break;
    +		case CFW_CMD_WAITBITS:
    +			aic3xxx_wait(ps, c[1].reg.bpod, c->bitop.mask,
    +				     c[1].reg.data);
    +			pc += 2;
    +			break;
    +		case CFW_CMD_LOCK:
    +			if (c->delay.delay)
    +				ps->ops->lock(ps->codec);
    +			else
    +				ps->ops->unlock(ps->codec);
    +			pc += 1;
    +			break;
    +		case CFW_CMD_BURST:
    +			ps->ops->bulk_write(ps->codec, c[1].reg.bpod,
    +					    c->bhdr.len, c[1].burst.data);
    +			pc += CFW_CMD_BURST_LEN(c->bhdr.len);
    +			break;
    +		case CFW_CMD_RBURST:
    +			ps->ops->bulk_read(ps->codec, c[1].reg.bpod,
    +					    c->bhdr.len, c[1].burst.data);
    +			pc += CFW_CMD_BURST_LEN(c->bhdr.len);
    +			break;
    +		case CFW_CMD_LOAD_VAR_IM:
    +			aic3xxx_set_bits(&var[c->ldst.dvar],
    +					 c->ldst.mask, c->ldst.svar);
    +			pc += 1;
    +			break;
    +		case CFW_CMD_LOAD_VAR_ID:
    +			if (c->ldst.svar != c->ldst.dvar) {
    +				aic3xxx_set_bits(&var[c->ldst.dvar],
    +						 c->ldst.mask,
    +						 var[c->ldst.svar]);
    +				pc += 1;
    +			} else {
    +				u8 data;
    +				data = ps->ops->reg_read(ps->codec,
    +							c[1].reg.bpod);
    +				aic3xxx_set_bits(&var[c->ldst.dvar],
    +						 c->ldst.mask, data);
    +				pc += 2;
    +			}
    +			break;
    +		case CFW_CMD_STORE_VAR:
    +			if (c->ldst.svar != c->ldst.dvar)
    +				ps->ops->set_bits(ps->codec,
    +						  c[1].reg.bpod,
    +						  var[c->ldst.dvar],
    +						  var[c->ldst.svar]);
    +			else
    +				ps->ops->set_bits(ps->codec,
    +						  c[1].reg.bpod,
    +						  c->ldst.mask,
    +						  var[c->ldst.svar]);
    +			pc += 2;
    +			break;
    +		case CFW_CMD_COND:
    +			cond = var[c->cond.svar] & c->cond.mask;
    +			pc += 1;
    +			break;
    +		case CFW_CMD_BRANCH:
    +			pc = c->branch.address;
    +			break;
    +		case CFW_CMD_BRANCH_IM:
    +			if (c->branch.match == cond)
    +				pc = c->branch.address;
    +			else
    +				pc += 1;
    +			break;
    +		case CFW_CMD_BRANCH_ID:
    +			if (var[c->branch.match] == cond)
    +				pc = c->branch.address;
    +			else
    +				pc += 1;
    +			break;
    +		case CFW_CMD_PRINT:
    +			{
    +				union cfw_cmd *parglist =
    +				    c + CFW_CMD_PRINT_ARG(c->print);
    +				printk(c->print.fmt,
    +				     var[parglist->print_arg[0]],
    +				     var[parglist->print_arg[1]],
    +				     var[parglist->print_arg[2]],
    +				     var[parglist->print_arg[3]]);
    +				pc += CFW_CMD_PRINT_LEN(c->print);
    +			}
    +			break;
    +		case CFW_CMD_OP_START ... CFW_CMD_OP_END:
    +			aic3xxx_cfw_op(ps, var, c->op);
    +			pc += 1;
    +			break;
    +		default:
    +			warn("Unknown cmd command %x. Skipped", c->cid);
    +			pc += 1;
    +			break;
    +		}
    +	}
    +}
    +
    +static void aic3xxx_wait(struct cfw_state *ps, unsigned int reg, u8 mask,
    +			 u8 data)
    +{
    +	while ((ps->ops->reg_read(ps->codec, reg) & mask) != data)
    +		mdelay(2);
    +}
    +
    +static void aic3xxx_set_bits(u8 *data, u8 mask, u8 val)
    +{
    +	*data = (*data & (~mask)) | (val & mask);
    +}
    +
    +static const struct {
    +	u32 mdsp;
    +	int buf_a, buf_b;
    +	u32 swap;
    +} csecs[] = {
    +	{
    +		.mdsp = AIC3XXX_COPS_MDSP_A,
    +		.swap = AIC3XXX_ABUF_MDSP_A,
    +		.buf_a = CFW_BLOCK_A_A_COEF,
    +		.buf_b = CFW_BLOCK_A_B_COEF
    +	},
    +	{
    +		.mdsp = AIC3XXX_COPS_MDSP_D,
    +		.swap = AIC3XXX_ABUF_MDSP_D1,
    +		.buf_a = CFW_BLOCK_D_A1_COEF,
    +		.buf_b = CFW_BLOCK_D_B1_COEF
    +	},
    +	{
    +		.mdsp = AIC3XXX_COPS_MDSP_D,
    +		.swap = AIC3XXX_ABUF_MDSP_D2,
    +		.buf_a = CFW_BLOCK_D_A2_COEF,
    +		.buf_b = CFW_BLOCK_D_B2_COEF
    +	},
    +};
    +static int aic3xxx_cfw_dlctl(struct cfw_state *ps, struct cfw_block *pb,
    +			     u32 mute_flags)
    +{
    +	int i, btype = pb->type;
    +	int run_state = ps->ops->lock(ps->codec);
    +
    +	DBG("Download CTL");
    +	for (i = 0; i < sizeof(csecs) / sizeof(csecs[0]); ++i) {
    +		if (csecs[i].buf_a != btype && csecs[i].buf_b != btype)
    +			continue;
    +		DBG("\tDownload once to %d", btype);
    +		aic3xxx_cfw_dlcmds(ps, pb);
    +		if (run_state & csecs[i].mdsp) {
    +			DBG("\tDownload again to make sure it reaches B");
    +			aic3xxx_cfw_mute(ps, 1, run_state & mute_flags);
    +			ps->ops->bswap(ps->codec, csecs[i].swap);
    +			aic3xxx_cfw_mute(ps, 0, run_state & mute_flags);
    +			aic3xxx_cfw_dlcmds(ps, pb);
    +		}
    +		break;
    +	}
    +	ps->ops->unlock(ps->codec);
    +	return 0;
    +}
    +
    +static int aic3xxx_cfw_dlcfg(struct cfw_state *ps, struct cfw_image *pim)
    +{
    +	int i, run_state, swap;
    +
    +	DBG("Download CFG %s", pim->name);
    +	run_state = ps->ops->lock(ps->codec);
    +	swap = 0;
    +	for (i = 0; i < sizeof(csecs) / sizeof(csecs[0]); ++i) {
    +		if (!pim->block[csecs[i].buf_a])
    +			continue;
    +		aic3xxx_cfw_dlcmds(ps, pim->block[csecs[i].buf_a]);
    +		aic3xxx_cfw_dlcmds(ps, pim->block[csecs[i].buf_b]);
    +		if (run_state & csecs[i].mdsp)
    +			swap |= csecs[i].swap;
    +	}
    +	if (swap) {
    +		aic3xxx_cfw_mute(ps, 1, run_state & pim->mute_flags);
    +		ps->ops->bswap(ps->codec, swap);
    +		aic3xxx_cfw_mute(ps, 0, run_state & pim->mute_flags);
    +		for (i = 0; i < sizeof(csecs) / sizeof(csecs[0]); ++i) {
    +			if (!pim->block[csecs[i].buf_a])
    +				continue;
    +			if (!(run_state & csecs[i].mdsp))
    +				continue;
    +			aic3xxx_cfw_dlcmds(ps, pim->block[csecs[i].buf_a]);
    +			aic3xxx_cfw_dlcmds(ps, pim->block[csecs[i].buf_b]);
    +		}
    +	}
    +	ps->ops->unlock(ps->codec);
    +	return 0;
    +}
    +
    +static int aic3xxx_cfw_dlimage(struct cfw_state *ps, struct cfw_image *pim)
    +{
    +	int i;
    +
    +	if (!pim)
    +		return 0;
    +	DBG("Download IMAGE %s", pim->name);
    +	for (i = 0; i < CFW_BLOCK_N; ++i)
    +		aic3xxx_cfw_dlcmds(ps, pim->block[i]);
    +	return 0;
    +}
    +
    +static int aic3xxx_cfw_mute(struct cfw_state *ps, int mute, u32 flags)
    +{
    +	if ((flags & AIC3XXX_COPS_MDSP_D) && (flags & AIC3XXX_COPS_MDSP_A))
    +		aic3xxx_cfw_transition_u(ps,
    +					 mute ? "AD_MUTE" : "AD_UNMUTE");
    +	else if (flags & AIC3XXX_COPS_MDSP_D)
    +		aic3xxx_cfw_transition_u(ps, mute ? "D_MUTE" : "D_UNMUTE");
    +	else if (flags & AIC3XXX_COPS_MDSP_A)
    +		aic3xxx_cfw_transition_u(ps, mute ? "A_MUTE" : "A_UNMUTE");
    +	return 0;
    +}
    +
    +static inline void *aic3xxx_cfw_ndx2ptr(void *p, u8 *base)
    +{
    +	return &base[(int)p];
    +}
    +static inline char *aic3xxx_cfw_desc(void *p, u8 *base)
    +{
    +	if (p)
    +		return aic3xxx_cfw_ndx2ptr(p, base);
    +	return NULL;
    +}
    +
    +static void aic3xxx_cfw_unpickle_image(struct cfw_image *im, void *p)
    +{
    +	int i;
    +
    +	im->desc = aic3xxx_cfw_desc(im->desc, p);
    +	for (i = 0; i < CFW_BLOCK_N; ++i)
    +		if (im->block[i])
    +			im->block[i] = aic3xxx_cfw_ndx2ptr(im->block[i], p);
    +}
    +
    +static void aic3xxx_cfw_unpickle_control(struct cfw_control *ct, void *p)
    +{
    +	int i;
    +
    +	ct->output = aic3xxx_cfw_ndx2ptr(ct->output, p);
    +	ct->desc = aic3xxx_cfw_desc(ct->desc, p);
    +	for (i = 0; i <= ct->imax; ++i)
    +		ct->output[i] = aic3xxx_cfw_ndx2ptr(ct->output[i], p);
    +}
    +
    +static unsigned int crc32(unsigned int *pdata, int n)
    +{
    +	u32 crc = 0, i, crc_poly = 0x04C11DB7;	/* CRC - 32 */
    +	u32 msb;
    +	u32 residue_value = 0;
    +	int bits;
    +
    +	for (i = 0; i < (n >> 2); i++) {
    +		bits = 32;
    +		while (--bits >= 0) {
    +			msb = crc & 0x80000000;
    +			crc = (crc << 1) ^ ((*pdata >> bits) & 1);
    +			if (msb)
    +				crc = crc ^ crc_poly;
    +		}
    +		pdata++;
    +	}
    +
    +	switch (n & 3) {
    +	case 0:
    +		break;
    +	case 1:
    +		residue_value = (*pdata & 0xFF);
    +		bits = 8;
    +		break;
    +	case 2:
    +		residue_value = (*pdata & 0xFFFF);
    +		bits = 16;
    +		break;
    +	case 3:
    +		residue_value = (*pdata & 0xFFFFFF);
    +		bits = 24;
    +		break;
    +	}
    +
    +	if (n & 3) {
    +		while (--bits >= 0) {
    +			msb = crc & 0x80000000;
    +			crc = (crc << 1) ^ ((residue_value >> bits) & 1);
    +			if (msb)
    +				crc = crc ^ crc_poly;
    +		}
    +	}
    +	return crc;
    +}
    +
    +static int crc_chk(void *p, int n)
    +{
    +	struct cfw_project *pjt = (void *) p;
    +	u32 crc = pjt->cksum, crc_comp;
    +
    +	pjt->cksum = 0;
    +	DBG("Entering crc %d", n);
    +	crc_comp = crc32(p, n);
    +	if (crc_comp != crc) {
    +		DBG("CRC mismatch 0x%08X != 0x%08X", crc, crc_comp);
    +		return 0;
    +	}
    +	DBG("CRC pass");
    +	pjt->cksum = crc;
    +	return 1;
    +}
    +
    +static struct cfw_project *aic3xxx_cfw_unpickle(void *p, int n)
    +{
    +	struct cfw_project *pjt = p;
    +	int i, j;
    +
    +	if (pjt->magic != CFW_FW_MAGIC || pjt->size != n ||
    +	    pjt->if_id != CFW_FW_IF_ID || !crc_chk(p, n)) {
    +		error("Version mismatch: unable to load firmware\n");
    +		return NULL;
    +	}
    +	DBG("Loaded firmware inside unpickle\n");
    +
    +	pjt->desc = aic3xxx_cfw_desc(pjt->desc, p);
    +	pjt->transition = aic3xxx_cfw_ndx2ptr(pjt->transition, p);
    +	for (i = 0; i < CFW_TRN_N; i++) {
    +		if (!pjt->transition[i])
    +			continue;
    +		pjt->transition[i] = aic3xxx_cfw_ndx2ptr(pjt->transition[i], p);
    +		pjt->transition[i]->desc = aic3xxx_cfw_desc(
    +						pjt->transition[i]->desc, p);
    +		pjt->transition[i]->block = aic3xxx_cfw_ndx2ptr(
    +						pjt->transition[i]->block, p);
    +	}
    +	pjt->pll = aic3xxx_cfw_ndx2ptr(pjt->pll, p);
    +	for (i = 0; i < pjt->npll; i++) {
    +		pjt->pll[i] = aic3xxx_cfw_ndx2ptr(pjt->pll[i], p);
    +		pjt->pll[i]->desc = aic3xxx_cfw_desc(pjt->pll[i]->desc, p);
    +		pjt->pll[i]->seq = aic3xxx_cfw_ndx2ptr(pjt->pll[i]->seq, p);
    +	}
    +
    +	pjt->pfw = aic3xxx_cfw_ndx2ptr(pjt->pfw, p);
    +	for (i = 0; i < pjt->npfw; i++) {
    +		DBG("loading pfw %d\n", i);
    +		pjt->pfw[i] = aic3xxx_cfw_ndx2ptr(pjt->pfw[i], p);
    +		pjt->pfw[i]->desc = aic3xxx_cfw_desc(pjt->pfw[i]->desc, p);
    +		if (pjt->pfw[i]->base) {
    +			pjt->pfw[i]->base = aic3xxx_cfw_ndx2ptr(
    +							pjt->pfw[i]->base, p);
    +			aic3xxx_cfw_unpickle_image(pjt->pfw[i]->base, p);
    +		}
    +		pjt->pfw[i]->ovly_cfg = aic3xxx_cfw_ndx2ptr(
    +						pjt->pfw[i]->ovly_cfg, p);
    +		for (j = 0; j < pjt->pfw[i]->novly * pjt->pfw[i]->ncfg; ++j) {
    +			pjt->pfw[i]->ovly_cfg[j] = aic3xxx_cfw_ndx2ptr(
    +						pjt->pfw[i]->ovly_cfg[j], p);
    +			aic3xxx_cfw_unpickle_image(pjt->pfw[i]->ovly_cfg[j], p);
    +		}
    +		if (pjt->pfw[i]->nctrl)
    +			pjt->pfw[i]->ctrl = aic3xxx_cfw_ndx2ptr(
    +							pjt->pfw[i]->ctrl, p);
    +		for (j = 0; j < pjt->pfw[i]->nctrl; ++j) {
    +			pjt->pfw[i]->ctrl[j] = aic3xxx_cfw_ndx2ptr(
    +						pjt->pfw[i]->ctrl[j], p);
    +			aic3xxx_cfw_unpickle_control(pjt->pfw[i]->ctrl[j], p);
    +		}
    +	}
    +
    +	DBG("loaded pfw's\n");
    +	pjt->mode = aic3xxx_cfw_ndx2ptr(pjt->mode, p);
    +	for (i = 0; i < pjt->nmode; i++) {
    +		pjt->mode[i] = aic3xxx_cfw_ndx2ptr(pjt->mode[i], p);
    +		pjt->mode[i]->desc = aic3xxx_cfw_desc(pjt->mode[i]->desc, p);
    +		if (pjt->mode[i]->entry)
    +			pjt->mode[i]->entry = aic3xxx_cfw_ndx2ptr(
    +						pjt->mode[i]->entry, p);
    +		if (pjt->mode[i]->exit)
    +			pjt->mode[i]->exit = aic3xxx_cfw_ndx2ptr(
    +						pjt->mode[i]->exit, p);
    +	}
    +	if (pjt->asoc_toc)
    +		pjt->asoc_toc = aic3xxx_cfw_ndx2ptr(pjt->asoc_toc, p);
    +	else {
    +		warn("asoc_toc not defined.  FW version mismatch?");
    +		return NULL;
    +	}
    +	DBG("loaded modes");
    +	return pjt;
    +}
    +static int aic3xxx_cfw_set_mode_id(struct cfw_state *ps)
    +{
    +	struct cfw_asoc_toc *toc = ps->pjt->asoc_toc;
    +	int i;
    +
    +	for (i = 0; i < toc->nentries; ++i) {
    +		if (toc->entry[i].cfg == ps->cur_cfg &&
    +		    toc->entry[i].mode == ps->cur_mode) {
    +			ps->cur_mode_id = i;
    +			return 0;
    +		}
    +	}
    +	DBG("Unknown mode,cfg combination [%d,%d]", ps->cur_mode,
    +	    ps->cur_cfg);
    +	return -1;
    +}
    +
    +/* **Code beyond this point is not compilable on host** */
    +
    +static int aic3xxx_get_control(struct snd_kcontrol *kcontrol,
    +			       struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct cfw_state *ps = (struct cfw_state *)kcontrol->private_value;
    +	struct cfw_pfw *pfw;
    +	int i;
    +
    +	if (ps->cur_pfw >= ps->pjt->npfw) {
    +		DBG("Not in MiniDSP mode");
    +		return 0;
    +	}
    +	pfw = ps->pjt->pfw[ps->cur_pfw];
    +	for (i = 0; i < pfw->nctrl; ++i) {
    +		if (!strcasecmp(kcontrol->id.name, pfw->ctrl[i]->name)) {
    +			struct cfw_control *pc = pfw->ctrl[i];
    +			ucontrol->value.integer.value[0] = pc->icur;
    +			return 0;
    +		}
    +	}
    +	return 0;
    +}
    +
    +static int aic3xxx_put_control(struct snd_kcontrol *kcontrol,
    +			       struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct cfw_state *ps = (struct cfw_state *)kcontrol->private_value;
    +
    +	aic3xxx_cfw_control(ps, kcontrol->id.name,
    +			    ucontrol->value.integer.value[0]);
    +	return 0;
    +}
    +
    +static int aic3xxx_info_control(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_info *ucontrol)
    +{
    +	struct cfw_state *ps = (struct cfw_state *)kcontrol->private_value;
    +	struct cfw_pfw *pfw;
    +	int i;
    +
    +	if (ps->cur_pfw >= ps->pjt->npfw) {
    +		DBG("Not in MiniDSP mode");
    +		return 0;
    +	}
    +	pfw = ps->pjt->pfw[ps->cur_pfw];
    +	for (i = 0; i < pfw->nctrl; ++i) {
    +		if (!strcasecmp(kcontrol->id.name, pfw->ctrl[i]->name)) {
    +			struct cfw_control *pc = pfw->ctrl[i];
    +			ucontrol->value.integer.min = 0;
    +			ucontrol->value.integer.max = pc->imax;
    +			if (pc->imax == 1)
    +				ucontrol->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
    +			else
    +				ucontrol->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    +		}
    +	}
    +
    +	ucontrol->count = 1;
    +	return 0;
    +}
    +int aic3xxx_cfw_add_controls(struct snd_soc_component *codec, struct cfw_state *ps)
    +{
    +	int i, j;
    +	struct cfw_pfw *pfw;
    +
    +	for (j = 0; j < ps->pjt->npfw; ++j) {
    +		pfw = ps->pjt->pfw[j];
    +
    +		for (i = 0; i < pfw->nctrl; ++i) {
    +			struct cfw_control *pc = pfw->ctrl[i];
    +			struct snd_kcontrol_new *generic_control =
    +			    kzalloc(sizeof(struct snd_kcontrol_new),
    +				    GFP_KERNEL);
    +			unsigned int *tlv_array =
    +			    kzalloc(4 * sizeof(unsigned int), GFP_KERNEL);
    +
    +			if (generic_control == NULL)
    +				return -ENOMEM;
    +			generic_control->access =
    +			    SNDRV_CTL_ELEM_ACCESS_TLV_READ |
    +			    SNDRV_CTL_ELEM_ACCESS_READWRITE;
    +			tlv_array[0] = SNDRV_CTL_TLVT_DB_SCALE;
    +			tlv_array[1] = 2 * sizeof(unsigned int);
    +			tlv_array[2] = pc->min;
    +			tlv_array[3] = ((pc->step) & TLV_DB_SCALE_MASK);
    +			if (pc->step > 0)
    +				generic_control->tlv.p = tlv_array;
    +			generic_control->name = pc->name;
    +			generic_control->private_value = (unsigned long) ps;
    +			generic_control->get = aic3xxx_get_control;
    +			generic_control->put = aic3xxx_put_control;
    +			generic_control->info = aic3xxx_info_control;
    +			generic_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
    +			snd_soc_add_component_controls(codec, generic_control, 1);
    +			DBG("Added control %s", pc->name);
    +		}
    +	}
    +	return 0;
    +
    +}
    +
    +
    +static int aic3xxx_get_mode(struct snd_kcontrol *kcontrol,
    +			    struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
    +	struct cfw_state *ps = (struct cfw_state *) e->mask;
    +
    +	ucontrol->value.enumerated.item[0] = ps->cur_mode_id;
    +
    +	return 0;
    +}
    +
    +static int aic3xxx_put_mode(struct snd_kcontrol *kcontrol,
    +			    struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
    +	struct cfw_state *ps = (struct cfw_state *) e->mask;
    +	struct cfw_asoc_toc *toc;
    +	int index, ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	toc = ps->pjt->asoc_toc;
    +
    +	index = ucontrol->value.enumerated.item[0];
    +	if (index < 0 || index >= toc->nentries) {
    +		aic3xxx_cfw_lock(ps, 0);
    +		return -EINVAL;
    +	}
    +	ret = aic3xxx_cfw_setmode_cfg_u(ps, toc->entry[index].mode,
    +				      toc->entry[index].cfg);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +int aic3xxx_cfw_add_modes(struct snd_soc_component *codec, struct cfw_state *ps)
    +{
    +	int j;
    +	struct cfw_asoc_toc *toc = ps->pjt->asoc_toc;
    +	struct soc_enum *mode_cfg_enum =
    +	    kzalloc(sizeof(struct soc_enum), GFP_KERNEL);
    +	struct snd_kcontrol_new *mode_cfg_control =
    +	    kzalloc(sizeof(struct snd_kcontrol_new), GFP_KERNEL);
    +	char **enum_texts;
    +
    +	if (mode_cfg_enum == NULL)
    +		goto mem_err;
    +	if (mode_cfg_control == NULL)
    +		goto mem_err;
    +
    +	mode_cfg_enum->texts = kzalloc(toc->nentries * sizeof(char *),
    +								GFP_KERNEL);
    +	if (mode_cfg_enum->texts == NULL)
    +		goto mem_err;
    +	/* Hack to overwrite the const * const pointer */
    +	enum_texts = (char **) mode_cfg_enum->texts;
    +
    +	for (j = 0; j < toc->nentries; j++)
    +		enum_texts[j] = toc->entry[j].etext;
    +
    +	mode_cfg_enum->reg = j;
    +	/* mode_cfg_enum->max = toc->nentries; */
    +	mode_cfg_enum->mask = (unsigned int) ps;
    +	mode_cfg_control->name = "Codec Firmware Setmode";
    +	mode_cfg_control->get = aic3xxx_get_mode;
    +	mode_cfg_control->put = aic3xxx_put_mode;
    +	/*mode_cfg_control->info = snd_soc_info_enum_ext;*/
    +	mode_cfg_control->private_value = (unsigned long) mode_cfg_enum;
    +	mode_cfg_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
    +	snd_soc_add_component_controls(codec, mode_cfg_control, 1);
    +	return 0;
    +mem_err:
    +	kfree(mode_cfg_control);
    +	kfree(mode_cfg_enum);
    +	kfree(mode_cfg_enum->texts);
    +	return -ENOMEM;
    +
    +}
    +
    +#if defined(CONFIG_AIC3111_CODEC) || defined(CONFIG_AIC3111_CORE)
    +
    +#	define AIC3XXX_CFW_DEVICE "aic3111_cfw"
    +#elif defined(CONFIG_AIC3256_CODEC) || defined(CONFIG_AIC3256_CORE)
    +
    +#	define AIC3XXX_CFW_DEVICE "aic3256_cfw"
    +#elif defined(CONFIG_AIC3262_CODEC) || defined(CONFIG_AIC3262_CORE)
    +#	define AIC3XXX_CFW_DEVICE "aic3262_cfw"
    +#else
    +#	define AIC3XXX_CFW_DEVICE "aic3xxx_cfw"
    +#endif
    +
    +static int aic3xxx_cfw_open(struct inode *in, struct file *filp)
    +{
    +	struct cfw_state *ps = container_of(in->i_cdev, struct cfw_state, cdev);
    +	if (ps->is_open) {
    +		warn("driver_open: device is already open");
    +		return -1;
    +	}
    +	ps->is_open++;
    +	filp->private_data = ps;
    +	return 0;
    +}
    +static int aic3xxx_cfw_release(struct inode *in, struct file *filp)
    +{
    +	struct cfw_state *ps = filp->private_data;
    +	ps->is_open--;
    +	return ps->is_open;
    +}
    +static long aic3xxx_cfw_ioctl(struct file *filp,
    +			unsigned int cmd, unsigned long arg)
    +{
    +	return 0;
    +}
    +static ssize_t aic3xxx_cfw_rw(struct file *filp, char __user *buf,
    +			   size_t count, loff_t *offset)
    +{
    +	struct cfw_state *ps = filp->private_data;
    +	struct cfw_block *kbuf = kmalloc(count, GFP_KERNEL);
    +	if (!kbuf || copy_from_user(kbuf, buf, count)) {
    +		warn("dev_rw: Allocation or copy failure");
    +		goto err;
    +	}
    +	if (count != CFW_BLOCK_SIZE(kbuf->ncmds)) {
    +		warn("dev_rw: Bad packet received\n");
    +		goto err;
    +	}
    +	aic3xxx_cfw_dlcmds(ps, kbuf);
    +	if (copy_to_user(buf, kbuf, count)) {
    +		warn("dev_rw: copy failure");
    +		goto err;
    +	}
    +	kfree(kbuf);
    +	return count;
    +err:
    +	kfree(kbuf);
    +	return -EINVAL;
    +}
    +
    +static const struct file_operations aic3xxx_cfw_fops = {
    +	.owner = THIS_MODULE,
    +	.open = aic3xxx_cfw_open,
    +	.release = aic3xxx_cfw_release,
    +	.read = aic3xxx_cfw_rw,
    +	.write = (ssize_t (*)(struct file *filp, const char __user *buf,
    +			size_t count, loff_t *offset))aic3xxx_cfw_rw,
    +	.unlocked_ioctl = aic3xxx_cfw_ioctl,
    +};
    +static int aic3xxx_driver_init(struct cfw_state *ps)
    +{
    +	int err;
    +
    +	dev_t dev = MKDEV(0, 0);
    +
    +	err = alloc_chrdev_region(&dev, 0, 1, AIC3XXX_CFW_DEVICE);
    +	if (err < 0) {
    +		warn("driver_init: Error allocating device number");
    +		return err;
    +	}
    +	warn("driver_init: Allocated Major Number: %d\n", MAJOR(dev));
    +
    +	cdev_init(&(ps->cdev), &aic3xxx_cfw_fops);
    +	ps->cdev.owner = THIS_MODULE;
    +	ps->cdev.ops = &aic3xxx_cfw_fops;
    +	ps->is_open = 0;
    +
    +	err = cdev_add(&(ps->cdev), dev, 1);
    +	if (err < 0) {
    +		warn("driver_init: cdev_add failed");
    +		unregister_chrdev_region(dev, 1);
    +		return err;
    +	}
    +	warn("driver_init: Registered cfw driver");
    +	return 0;
    +}
    +
    +MODULE_DESCRIPTION("ASoC tlv320aic3xxx codec driver firmware functions");
    +MODULE_AUTHOR("Hari Rajagopala <harik@ti.com>");
    +MODULE_LICENSE("GPL");
    +
    diff --git a/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h b/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h
    new file mode 100644
    index 000000000..c58613359
    --- /dev/null
    +++ b/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h
    @@ -0,0 +1,95 @@
    +/*
    + * aic3xxx_cfw_ops.h  --  SoC audio for TI OMAP44XX SDP
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#ifndef AIC3XXX_CFW_OPS_H_
    +#define AIC3XXX_CFW_OPS_H_
    +
    +#include <linux/mutex.h>
    +#include <sound/soc.h>
    +#include <linux/cdev.h>
    +
    +struct cfw_project;
    +struct aic3xxx_codec_ops;
    +
    +struct cfw_state {
    +	struct cfw_project *pjt;
    +	const struct aic3xxx_codec_ops  *ops;
    +	struct snd_soc_component *codec;
    +	struct mutex mutex;
    +	int cur_mode_id;
    +	int cur_pll;
    +	int cur_mode;
    +	int cur_pfw;
    +	int cur_ovly;
    +	int cur_cfg;
    +	struct cdev cdev;
    +	int is_open;
    +};
    +
    +int aic3xxx_cfw_init(struct cfw_state *ps, const struct aic3xxx_codec_ops *ops,
    +		     struct snd_soc_component *codec);
    +int aic3xxx_cfw_lock(struct cfw_state *ps, int lock);
    +int aic3xxx_cfw_reload(struct cfw_state *ps, void *pcfw, int n);
    +int aic3xxx_cfw_setmode(struct cfw_state *ps, int mode);
    +int aic3xxx_cfw_setmode_cfg(struct cfw_state *ps, int mode, int cfg);
    +int aic3xxx_cfw_setcfg(struct cfw_state *ps, int cfg);
    +int aic3xxx_cfw_transition(struct cfw_state *ps, char *ttype);
    +int aic3xxx_cfw_set_pll(struct cfw_state *ps, int asi);
    +int aic3xxx_cfw_control(struct cfw_state *ps, char *cname, int param);
    +int aic3xxx_cfw_add_controls(struct snd_soc_component *codec, struct cfw_state *ps);
    +int aic3xxx_cfw_add_modes(struct snd_soc_component *codec, struct cfw_state *ps);
    +
    +
    +#define AIC3XXX_COPS_MDSP_D_L    (0x00000002u)
    +#define AIC3XXX_COPS_MDSP_D_R    (0x00000001u)
    +#define AIC3XXX_COPS_MDSP_D      (AIC3XXX_COPS_MDSP_D_L|AIC3XXX_COPS_MDSP_D_R)
    +
    +#define AIC3XXX_COPS_MDSP_A_L    (0x00000020u)
    +#define AIC3XXX_COPS_MDSP_A_R    (0x00000010u)
    +#define AIC3XXX_COPS_MDSP_A      (AIC3XXX_COPS_MDSP_A_L|AIC3XXX_COPS_MDSP_A_R)
    +
    +#define AIC3XXX_COPS_MDSP_ALL    (AIC3XXX_COPS_MDSP_D|AIC3XXX_COPS_MDSP_A)
    +
    +#define AIC3XXX_ABUF_MDSP_D1 (0x00000001u)
    +#define AIC3XXX_ABUF_MDSP_D2 (0x00000002u)
    +#define AIC3XXX_ABUF_MDSP_A  (0x00000010u)
    +#define AIC3XXX_ABUF_MDSP_ALL \
    +		(AIC3XXX_ABUF_MDSP_D1|AIC3XXX_ABUF_MDSP_D2|AIC3XXX_ABUF_MDSP_A)
    +
    +
    +struct aic3xxx_codec_ops {
    +	int (*reg_read) (struct snd_soc_component *codec, unsigned int reg);
    +	int (*reg_write) (struct snd_soc_component *codec, unsigned int reg,
    +					unsigned char val);
    +	int (*set_bits) (struct snd_soc_component *codec, unsigned int reg,
    +					unsigned char mask, unsigned char val);
    +	int (*bulk_read) (struct snd_soc_component *codec, unsigned int reg,
    +					int count, u8 *buf);
    +	int (*bulk_write) (struct snd_soc_component *codec, unsigned int reg,
    +					int count, const u8 *buf);
    +	int (*lock) (struct snd_soc_component *codec);
    +	int (*unlock) (struct snd_soc_component *codec);
    +	int (*stop) (struct snd_soc_component *codec, int mask);
    +	int (*restore) (struct snd_soc_component *codec, int runstate);
    +	int (*bswap) (struct snd_soc_component *codec, int mask);
    +};
    +
    +MODULE_LICENSE("GPL");
    +
    +#endif
    diff --git a/sound/soc/codecs/tlv320aic326x.c b/sound/soc/codecs/tlv320aic326x.c
    new file mode 100644
    index 000000000..9d7b0c0b7
    --- /dev/null
    +++ b/sound/soc/codecs/tlv320aic326x.c
    @@ -0,0 +1,2640 @@
    +/*
    + * linux/sound/soc/codecs/tlv320aic326x.c
    + *
    + * Copyright (C) 2011 Texas Instruments Inc.,
    + *
    + * This package is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2 as
    + * published by the Free Software Foundation.
    + *
    + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
    + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    + *
    + * The TLV320AIC3262 is a flexible, low-power, low-voltage stereo audio
    + * codec with digital microphone inputs and programmable outputs.
    + *
    + * History:
    + *
    + * Rev 0.1   ASoC driver support    TI	20-01-2011
    + *
    + *		The AIC325x ASoC driver is ported for the codec AIC3262.
    + * Rev 0.2   ASoC driver support    TI	21-03-2011
    + *		The AIC326x ASoC driver is updated for linux 2.6.32 Kernel.
    + * Rev 0.3   ASoC driver support    TI	   20-04-2011
    + *		The AIC326x ASoC driver is ported to 2.6.35 omap4 kernel
    + */
    +
    +/*
    + *****************************************************************************
    + * INCLUDES
    + *****************************************************************************
    + */
    +
    +#include <linux/module.h>
    +#include <linux/moduleparam.h>
    +#include <linux/init.h>
    +#include <linux/delay.h>
    +#include <linux/pm.h>
    +#include <linux/i2c.h>
    +#include <linux/pm_runtime.h>
    +#include <linux/spi/spi.h>
    +#include <linux/platform_device.h>
    +#include <sound/jack.h>
    +#include <linux/irq.h>
    +#include <linux/interrupt.h>
    +#include <linux/cdev.h>
    +#include <linux/slab.h>
    +#include <linux/firmware.h>
    +#include <linux/input.h>
    +
    +#include <sound/tlv.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 <linux/mfd/tlv320aic3262-registers.h>
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +#include "aic3xxx/aic3xxx_cfw_ops.h"
    +
    +#include "tlv320aic326x.h"
    +
    +/*****************************************************************************
    +			 Macros
    +******************************************************************************
    +
    +******************************************************************************
    +		  Function Prototype
    +******************************************************************************/
    +
    +static int aic3262_hw_params(struct snd_pcm_substream *substream,
    +			     struct snd_pcm_hw_params *params,
    +			     struct snd_soc_dai *dai);
    +
    +static int aic3262_mute(struct snd_soc_dai *dai, int mute, int direction);
    +
    +static int aic3262_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt);
    +
    +static int aic3262_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
    +				unsigned int Fin, unsigned int Fout);
    +
    +static int aic3262_set_bias_level(struct snd_soc_component *codec,
    +				  enum snd_soc_bias_level level);
    +
    +static int aic3262_set_mode_get(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_value *ucontrol);
    +static int aic3262_set_mode_put(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_value *ucontrol);
    +
    +static int aic326x_adc_dsp_event(struct snd_soc_dapm_widget *w,
    +				 struct snd_kcontrol *kcontrol, int event);
    +static int aic3262_get_runstate(struct snd_soc_component *codec);
    +static int aic3262_dsp_pwrdwn_status(struct snd_soc_component *codec);
    +static int aic3262_dsp_pwrup(struct snd_soc_component *codec, int state);
    +static int aic3262_restart_dsps_sync(struct snd_soc_component *codec, int rs);
    +
    +static inline unsigned int dsp_non_sync_mode(unsigned int state)
    +			{ return (!((state & 0x03) && (state & 0x30))); }
    +
    +static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0);
    +static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1200, 50, 0);
    +static const DECLARE_TLV_DB_SCALE(spk_gain_tlv, 600, 600, 0);
    +static const DECLARE_TLV_DB_SCALE(output_gain_tlv, -600, 100, 1);
    +static const DECLARE_TLV_DB_SCALE(micpga_gain_tlv, 0, 50, 0);
    +static const DECLARE_TLV_DB_SCALE(adc_fine_gain_tlv, -40, 10, 0);
    +static const DECLARE_TLV_DB_SCALE(beep_gen_volume_tlv, -6300, 100, 0);
    +
    +/* Chip-level Input and Output CM Mode Controls */
    +static const char * const input_common_mode_text[] = {
    +	"0.9v", "0.75v"
    +};
    +
    +static const char * const output_common_mode_text[] = {
    +	"Input CM", "1.25v", "1.5v", "1.65v"
    +};
    +
    +static const struct soc_enum input_cm_mode =
    +SOC_ENUM_SINGLE(AIC3262_CM_REG, 2, 2, input_common_mode_text);
    +
    +static const struct soc_enum output_cm_mode =
    +SOC_ENUM_SINGLE(AIC3262_CM_REG, 0, 4, output_common_mode_text);
    +/*
    + *****************************************************************************
    + * Structure Initialization
    + *****************************************************************************
    + */
    +static const struct snd_kcontrol_new aic3262_snd_controls[] = {
    +	/* Output */
    +#ifndef DAC_INDEPENDENT_VOL
    +	/* sound new kcontrol for PCM Playback volume control */
    +
    +	SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
    +				AIC3262_DAC_LVOL, AIC3262_DAC_RVOL, 0,
    +				0x81, 0xaf, dac_vol_tlv),
    +#endif
    +	/*HP Driver Gain Control */
    +	SOC_DOUBLE_R_SX_TLV("HeadPhone Driver Amplifier Volume",
    +				AIC3262_HPL_VOL, AIC3262_HPR_VOL, 0, 0x39,
    +				0x15, output_gain_tlv),
    +	/*LO Driver Gain Control */
    +	SOC_DOUBLE_TLV("Speaker Amplifier Volume", AIC3262_SPK_AMP_CNTL_R4, 4,
    +			0, 5, 0, spk_gain_tlv),
    +
    +	SOC_DOUBLE_R_SX_TLV("Receiver Amplifier Volume",
    +				AIC3262_REC_AMP_CNTL_R5, AIC3262_RAMPR_VOL, 0,
    +				0x39, 0x24, output_gain_tlv),
    +
    +	SOC_DOUBLE_R_SX_TLV("PCM Capture Volume", AIC3262_LADC_VOL,
    +				AIC3262_RADC_VOL, 0, 0x68, 0x41,
    +				adc_vol_tlv),
    +
    +	SOC_DOUBLE_R_TLV("MicPGA Volume Control", AIC3262_MICL_PGA,
    +			 AIC3262_MICR_PGA, 0, 0x5F, 0, micpga_gain_tlv),
    +
    +	SOC_DOUBLE_TLV("PCM Capture Fine Gain Volume", AIC3262_ADC_FINE_GAIN,
    +			4, 0, 5, 1, adc_fine_gain_tlv),
    +
    +	SOC_DOUBLE("ADC channel mute", AIC3262_ADC_FINE_GAIN, 7, 3, 1, 0),
    +
    +	SOC_DOUBLE("DAC MUTE", AIC3262_DAC_MVOL_CONF, 2, 3, 1, 1),
    +
    +	SOC_SINGLE("RESET", AIC3262_RESET_REG, 0, 1, 0),
    +
    +	SOC_SINGLE("DAC VOL SOFT STEPPING", AIC3262_DAC_MVOL_CONF, 0, 2, 0),
    +
    +	SOC_SINGLE("DAC AUTO MUTE CONTROL", AIC3262_DAC_MVOL_CONF, 4, 7, 0),
    +
    +	SOC_SINGLE("RIGHT MODULATOR SETUP", AIC3262_DAC_MVOL_CONF, 7, 1, 0),
    +
    +	SOC_SINGLE("ADC Volume soft stepping", AIC3262_ADC_CHANNEL_POW,
    +		   0, 3, 0),
    +
    +	SOC_SINGLE("Mic Bias ext independent enable", AIC3262_MIC_BIAS_CNTL,
    +		   7, 1, 0),
    +
    +	SOC_SINGLE("MICBIAS EXT Power Level", AIC3262_MIC_BIAS_CNTL, 4, 3, 0),
    +
    +	SOC_SINGLE("MICBIAS INT Power Level", AIC3262_MIC_BIAS_CNTL, 0, 3, 0),
    +
    +	SOC_SINGLE("BEEP_GEN_EN", AIC3262_BEEP_CNTL_R1, 7, 1, 0),
    +
    +	SOC_DOUBLE_R("BEEP_VOL_CNTL", AIC3262_BEEP_CNTL_R1,
    +		     AIC3262_BEEP_CNTL_R2, 0, 0x0F, 1),
    +
    +	SOC_SINGLE("BEEP_MAS_VOL", AIC3262_BEEP_CNTL_R2, 6, 3, 0),
    +
    +	SOC_SINGLE("DAC PRB Selection", AIC3262_DAC_PRB, 0, 26, 0),
    +
    +	SOC_SINGLE("ADC PRB Selection", AIC3262_ADC_PRB, 0, 18, 0),
    +
    +	SOC_ENUM("Input CM mode", input_cm_mode),
    +
    +	SOC_ENUM("Output CM mode", output_cm_mode),
    +
    +	SOC_SINGLE_EXT("FIRMWARE SET MODE", SND_SOC_NOPM, 0, 0xffff, 0,
    +			aic3262_set_mode_get, aic3262_set_mode_put),
    +};
    +
    +/*
    + *----------------------------------------------------------------------------
    + * @struct  snd_soc_component_dai |
    + *	It is SoC Codec DAI structure which has DAI capabilities viz.,
    + *	playback and capture, DAI runtime information viz. state of DAI
    + *			and pop wait state, and DAI private data.
    + *	The AIC3262 rates ranges from 8k to 192k
    + *	The PCM bit format supported are 16, 20, 24 and 32 bits
    + *----------------------------------------------------------------------------
    + */
    +struct snd_soc_dai_ops aic3262_asi1_dai_ops = {
    +	.hw_params = aic3262_hw_params,
    +	.mute_stream = aic3262_mute,
    +	.set_fmt = aic3262_set_dai_fmt,
    +	.set_pll = aic3262_dai_set_pll,
    +};
    +
    +struct snd_soc_dai_ops aic3262_asi2_dai_ops = {
    +	.hw_params = aic3262_hw_params,
    +	.mute_stream = aic3262_mute,
    +	.set_fmt = aic3262_set_dai_fmt,
    +	.set_pll = aic3262_dai_set_pll,
    +};
    +
    +struct snd_soc_dai_ops aic3262_asi3_dai_ops = {
    +	.hw_params = aic3262_hw_params,
    +	.mute_stream = aic3262_mute,
    +	.set_fmt = aic3262_set_dai_fmt,
    +	.set_pll = aic3262_dai_set_pll,
    +};
    +
    +struct snd_soc_dai_driver aic326x_dai_driver[] = {
    +	{
    +	 .name = "aic326x-asi1",
    +	 .playback = {
    +		      .stream_name = "ASI1 Playback",
    +		      .channels_min = 1,
    +		      .channels_max = 8,
    +		      .rates = AIC3262_RATES,
    +		      .formats = AIC3262_FORMATS,
    +		      },
    +	 .capture = {
    +		     .stream_name = "ASI1 Capture",
    +		     .channels_min = 1,
    +		     .channels_max = 8,
    +		     .rates = AIC3262_RATES,
    +		     .formats = AIC3262_FORMATS,
    +		     },
    +	 .ops = &aic3262_asi1_dai_ops,
    +	 },
    +	{
    +	 .name = "aic326x-asi2",
    +	 .playback = {
    +		      .stream_name = "ASI2 Playback",
    +		      .channels_min = 1,
    +		      .channels_max = 2,
    +		      .rates = AIC3262_RATES,
    +		      .formats = AIC3262_FORMATS,
    +		      },
    +	 .capture = {
    +		     .stream_name = "ASI2 Capture",
    +		     .channels_min = 1,
    +		     .channels_max = 2,
    +		     .rates = AIC3262_RATES,
    +		     .formats = AIC3262_FORMATS,
    +		     },
    +	 .ops = &aic3262_asi2_dai_ops,
    +	 },
    +	{
    +	 .name = "aic326x-asi3",
    +	 .playback = {
    +		      .stream_name = "ASI3 Playback",
    +		      .channels_min = 1,
    +		      .channels_max = 2,
    +		      .rates = AIC3262_RATES,
    +		      .formats = AIC3262_FORMATS,
    +		      },
    +	 .capture = {
    +		     .stream_name = "ASI3 Capture",
    +		     .channels_min = 1,
    +		     .channels_max = 2,
    +		     .rates = AIC3262_RATES,
    +		     .formats = AIC3262_FORMATS,
    +		     },
    +	 .ops = &aic3262_asi3_dai_ops,
    +	 },
    +
    +};
    +
    +static const unsigned int adc_ma_tlv[] = {
    +	TLV_DB_RANGE_HEAD(7),
    +	1, 1, TLV_DB_SCALE_ITEM(-3610, 0, 0),
    +	2, 2, TLV_DB_SCALE_ITEM(-3010, 0, 0),
    +	3, 3, TLV_DB_SCALE_ITEM(-2660, 0, 0),
    +	4, 4, TLV_DB_SCALE_ITEM(-2410, 0, 0),
    +	5, 7, TLV_DB_SCALE_ITEM(-2210, 1500, 0),
    +	8, 11, TLV_DB_SCALE_ITEM(-1810, 1000, 0),
    +	12, 41 , TLV_DB_SCALE_ITEM(-1450, 500, 0)
    +};
    +
    +static const DECLARE_TLV_DB_SCALE(lo_hp_tlv, -7830, 50, 0);
    +static const struct snd_kcontrol_new mal_pga_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("IN1 Left Capture Switch", AIC3262_MA_CNTL, 5, 1, 0),
    +	SOC_DAPM_SINGLE_TLV("Left MicPGA Volume", AIC3262_LADC_PGA_MAL_VOL,
    +				0, 0x3f, 1, adc_ma_tlv),
    +};
    +
    +static const struct snd_kcontrol_new mar_pga_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("IN1 Right Capture Switch", AIC3262_MA_CNTL, 4, 1, 0),
    +	SOC_DAPM_SINGLE_TLV("Right MicPGA Volume", AIC3262_RADC_PGA_MAR_VOL,
    +				0, 0x3f, 1, adc_ma_tlv),
    +};
    +
    +/* Left HPL Mixer */
    +static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("MA Left Playback Switch", AIC3262_HP_AMP_CNTL_R1, 7, 1,
    +			0),
    +	SOC_DAPM_SINGLE("Left DAC Playback Switch", AIC3262_HP_AMP_CNTL_R1,
    +			5, 1, 0),
    +	SOC_DAPM_SINGLE_TLV("LO Left-B1 Playback Volume",
    +				AIC3262_HP_AMP_CNTL_R2, 0, 0x7f, 1, lo_hp_tlv),
    +};
    +
    +/* Right HPR Mixer */
    +static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE_TLV("LO Right-B1 Playback Volume",
    +				AIC3262_HP_AMP_CNTL_R3, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE("Left DAC Playback Switch", AIC3262_HP_AMP_CNTL_R1,
    +			2, 1, 0),
    +	SOC_DAPM_SINGLE("Right DAC Playback Switch", AIC3262_HP_AMP_CNTL_R1,
    +			4, 1, 0),
    +	SOC_DAPM_SINGLE("MA Right Playback Switch", AIC3262_HP_AMP_CNTL_R1,
    +			6, 1, 0),
    +};
    +
    +/* Left LOL Mixer */
    +static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("MA Left Playback Switch", AIC3262_LINE_AMP_CNTL_R2,
    +			7, 1, 0),
    +	SOC_DAPM_SINGLE("IN1 Left-B Capture Switch", AIC3262_LINE_AMP_CNTL_R2,
    +			3, 1, 0),
    +	SOC_DAPM_SINGLE("Left DAC Playback Switch", AIC3262_LINE_AMP_CNTL_R1,
    +			7, 1, 0),
    +	SOC_DAPM_SINGLE("Right DAC Playback Switch", AIC3262_LINE_AMP_CNTL_R1,
    +			5, 1, 0),
    +};
    +
    +/* Right LOR Mixer */
    +static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("LO Left Playback Switch", AIC3262_LINE_AMP_CNTL_R1,
    +			2, 1, 0),
    +	SOC_DAPM_SINGLE("Right DAC Playback Switch", AIC3262_LINE_AMP_CNTL_R1,
    +			6, 1, 0),
    +	SOC_DAPM_SINGLE("MA Right Playback Switch", AIC3262_LINE_AMP_CNTL_R2,
    +			6, 1, 0),
    +	SOC_DAPM_SINGLE("IN1 Right-B Capture Switch", AIC3262_LINE_AMP_CNTL_R2,
    +			0, 1, 0),
    +};
    +
    +/* Left SPKL Mixer */
    +static const struct snd_kcontrol_new spkl_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("MA Left Playback Switch", AIC3262_SPK_AMP_CNTL_R1,
    +			7, 1, 0),
    +	SOC_DAPM_SINGLE_TLV("LO Left Playback Volume",
    +				AIC3262_SPK_AMP_CNTL_R2, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE("SPR_IN Switch", AIC3262_SPK_AMP_CNTL_R1, 2, 1, 0),
    +};
    +
    +/* Right SPKR Mixer */
    +static const struct snd_kcontrol_new spkr_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE_TLV("LO Right Playback Volume",
    +				AIC3262_SPK_AMP_CNTL_R3, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE("MA Right Playback Switch",
    +			AIC3262_SPK_AMP_CNTL_R1, 6, 1, 0),
    +};
    +
    +/* REC Mixer */
    +static const struct snd_kcontrol_new rec_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE_TLV("LO Left-B2 Playback Volume",
    +				AIC3262_RAMP_CNTL_R1, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE_TLV("IN1 Left Capture Volume",
    +				AIC3262_IN1L_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE_TLV("IN1 Right Capture Volume",
    +				AIC3262_IN1R_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE_TLV("LO Right-B2 Playback Volume",
    +				AIC3262_RAMP_CNTL_R2, 0, 0x7f, 1, lo_hp_tlv),
    +};
    +
    +/* Left Input Mixer */
    +static const struct snd_kcontrol_new left_input_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("IN1 Left Capture Switch", AIC3262_LMIC_PGA_PIN,
    +			6, 3, 0),
    +	SOC_DAPM_SINGLE("IN2 Left Capture Switch", AIC3262_LMIC_PGA_PIN,
    +			4, 3, 0),
    +	SOC_DAPM_SINGLE("IN3 Left Capture Switch", AIC3262_LMIC_PGA_PIN,
    +			2, 3, 0),
    +	SOC_DAPM_SINGLE("IN4 Left Capture Switch", AIC3262_LMIC_PGA_PM_IN4,
    +			5, 1, 0),
    +	SOC_DAPM_SINGLE("IN1 Right Capture Switch", AIC3262_LMIC_PGA_PIN,
    +			0, 3, 0),
    +	SOC_DAPM_SINGLE("IN2 Right Capture Switch", AIC3262_LMIC_PGA_MIN,
    +			4, 3, 0),
    +	SOC_DAPM_SINGLE("IN3 Right Capture Switch", AIC3262_LMIC_PGA_MIN,
    +			2, 3, 0),
    +	SOC_DAPM_SINGLE("IN4 Right Capture Switch", AIC3262_LMIC_PGA_PM_IN4,
    +			4, 1, 0),
    +	SOC_DAPM_SINGLE("CM2 Left Capture Switch", AIC3262_LMIC_PGA_MIN,
    +			0, 3, 0),
    +	SOC_DAPM_SINGLE("CM1 Left Capture Switch", AIC3262_LMIC_PGA_MIN,
    +			6, 3, 0),
    +};
    +
    +/* Right Input Mixer */
    +static const struct snd_kcontrol_new right_input_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("IN1 Right Capture Switch", AIC3262_RMIC_PGA_PIN,
    +			6, 3, 0),
    +	SOC_DAPM_SINGLE("IN2 Right Capture Switch", AIC3262_RMIC_PGA_PIN,
    +			4, 3, 0),
    +	SOC_DAPM_SINGLE("IN3 Right Capture Switch", AIC3262_RMIC_PGA_PIN,
    +			2, 3, 0),
    +	SOC_DAPM_SINGLE("IN4 Right Capture Switch", AIC3262_RMIC_PGA_PM_IN4,
    +			5, 1, 0),
    +	SOC_DAPM_SINGLE("IN2 Left Capture Switch", AIC3262_RMIC_PGA_PIN,
    +			0, 3, 0),
    +	SOC_DAPM_SINGLE("IN1 Left Capture Switch", AIC3262_RMIC_PGA_MIN,
    +			4, 3, 0),
    +	SOC_DAPM_SINGLE("IN3 Left Capture Switch", AIC3262_RMIC_PGA_MIN,
    +			2, 3, 0),
    +	SOC_DAPM_SINGLE("IN4 Left Capture Switch", AIC3262_RMIC_PGA_PM_IN4,
    +			4, 1, 0),
    +	SOC_DAPM_SINGLE("CM1 Right Capture Switch", AIC3262_RMIC_PGA_MIN,
    +			6, 3, 0),
    +	SOC_DAPM_SINGLE("CM2 Right Capture Switch", AIC3262_RMIC_PGA_MIN,
    +			0, 3, 0),
    +};
    +
    +static const char * const asi1lin_text[] = {
    +	"Off", "ASI1 Left In", "ASI1 Right In", "ASI1 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi1lin_enum, AIC3262_ASI1_DAC_OUT_CNTL, 6, asi1lin_text);
    +
    +static const struct snd_kcontrol_new asi1lin_control =
    +SOC_DAPM_ENUM("ASI1LIN Route", asi1lin_enum);
    +
    +static const char * const asi1rin_text[] = {
    +	"Off", "ASI1 Right In", "ASI1 Left In", "ASI1 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi1rin_enum, AIC3262_ASI1_DAC_OUT_CNTL, 4, asi1rin_text);
    +
    +static const struct snd_kcontrol_new asi1rin_control =
    +SOC_DAPM_ENUM("ASI1RIN Route", asi1rin_enum);
    +
    +static const char * const asi2lin_text[] = {
    +	"Off", "ASI2 Left In", "ASI2 Right In", "ASI2 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi2lin_enum, AIC3262_ASI2_DAC_OUT_CNTL, 6, asi2lin_text);
    +
    +static const struct snd_kcontrol_new asi2lin_control =
    +SOC_DAPM_ENUM("ASI2LIN Route", asi2lin_enum);
    +
    +static const char * const asi2rin_text[] = {
    +	"Off", "ASI2 Right In", "ASI2 Left In", "ASI2 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi2rin_enum, AIC3262_ASI2_DAC_OUT_CNTL, 4, asi2rin_text);
    +
    +static const struct snd_kcontrol_new asi2rin_control =
    +SOC_DAPM_ENUM("ASI2RIN Route", asi2rin_enum);
    +
    +static const char * const asi3lin_text[] = {
    +	"Off", "ASI3 Left In", "ASI3 Right In", "ASI3 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi3lin_enum, AIC3262_ASI3_DAC_OUT_CNTL, 6, asi3lin_text);
    +
    +static const struct snd_kcontrol_new asi3lin_control =
    +SOC_DAPM_ENUM("ASI3LIN Route", asi3lin_enum);
    +
    +static const char * const asi3rin_text[] = {
    +	"Off", "ASI3 Right In", "ASI3 Left In", "ASI3 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi3rin_enum, AIC3262_ASI3_DAC_OUT_CNTL, 4, asi3rin_text);
    +
    +static const struct snd_kcontrol_new asi3rin_control =
    +SOC_DAPM_ENUM("ASI3RIN Route", asi3rin_enum);
    +
    +static const char * const dacminidspin1_text[] = {
    +	"ASI1 In", "ASI2 In", "ASI3 In", "ADC MiniDSP Out"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dacminidspin1_enum, AIC3262_MINIDSP_DATA_PORT_CNTL, 4,
    +		     dacminidspin1_text);
    +
    +static const struct snd_kcontrol_new dacminidspin1_control =
    +SOC_DAPM_ENUM("DAC MiniDSP IN1 Route Sel", dacminidspin1_enum);
    +
    +static const char * const dacminidspin2_text[] = {
    +	"ASI1 In", "ASI2 In", "ASI3 In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dacminidspin2_enum, AIC3262_MINIDSP_DATA_PORT_CNTL, 2,
    +		     dacminidspin2_text);
    +
    +static const struct snd_kcontrol_new dacminidspin2_control =
    +SOC_DAPM_ENUM("DAC MiniDSP IN2 Route Sel", dacminidspin2_enum);
    +
    +static const char * const dacminidspin3_text[] = {
    +	"ASI1 In", "ASI2 In", "ASI3 In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dacminidspin3_enum, AIC3262_MINIDSP_DATA_PORT_CNTL, 0,
    +		     dacminidspin3_text);
    +
    +static const struct snd_kcontrol_new dacminidspin3_control =
    +SOC_DAPM_ENUM("DAC MiniDSP IN3 Route Sel", dacminidspin3_enum);
    +
    +static const char * const adcdac_route_text[] = {
    +	"Off",
    +	"On",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(adcdac_enum, 0, 2, adcdac_route_text);
    +
    +static const struct snd_kcontrol_new adcdacroute_control =
    +SOC_DAPM_ENUM("ADC DAC Route", adcdac_enum);
    +
    +static const char * const dout1_text[] = {
    +	"ASI1 Out",
    +	"DIN1 Bypass",
    +	"DIN2 Bypass",
    +	"DIN3 Bypass",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dout1_enum, AIC3262_ASI1_DOUT_CNTL, 0, dout1_text);
    +static const struct snd_kcontrol_new dout1_control =
    +SOC_DAPM_ENUM("DOUT1 Route", dout1_enum);
    +
    +static const char * const dout2_text[] = {
    +	"ASI2 Out",
    +	"DIN1 Bypass",
    +	"DIN2 Bypass",
    +	"DIN3 Bypass",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dout2_enum, AIC3262_ASI2_DOUT_CNTL, 0, dout2_text);
    +static const struct snd_kcontrol_new dout2_control =
    +SOC_DAPM_ENUM("DOUT2 Route", dout2_enum);
    +
    +static const char * const dout3_text[] = {
    +	"ASI3 Out",
    +	"DIN1 Bypass",
    +	"DIN2 Bypass",
    +	"DIN3 Bypass",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dout3_enum, AIC3262_ASI3_DOUT_CNTL, 0, dout3_text);
    +static const struct snd_kcontrol_new dout3_control =
    +SOC_DAPM_ENUM("DOUT3 Route", dout3_enum);
    +
    +static const char * const asi1out_text[] = {
    +	"Off",
    +	"ADC MiniDSP Out1",
    +	"ASI1In Bypass",
    +	"ASI2In Bypass",
    +	"ASI3In Bypass",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi1out_enum, AIC3262_ASI1_ADC_INPUT_CNTL,
    +		     0, asi1out_text);
    +static const struct snd_kcontrol_new asi1out_control =
    +SOC_DAPM_ENUM("ASI1OUT Route", asi1out_enum);
    +
    +static const char * const asi2out_text[] = {
    +	"Off",
    +	"ADC MiniDSP Out1",
    +	"ASI1In Bypass",
    +	"ASI2In Bypass",
    +	"ASI3In Bypass",
    +	"ADC MiniDSP Out2",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi2out_enum, AIC3262_ASI2_ADC_INPUT_CNTL,
    +		     0, asi2out_text);
    +static const struct snd_kcontrol_new asi2out_control =
    +SOC_DAPM_ENUM("ASI2OUT Route", asi2out_enum);
    +static const char * const asi3out_text[] = {
    +	"Off",
    +	"ADC MiniDSP Out1",
    +	"ASI1In Bypass",
    +	"ASI2In Bypass",
    +	"ASI3In Bypass",
    +	"Reserved",
    +	"ADC MiniDSP Out3",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi3out_enum, AIC3262_ASI3_ADC_INPUT_CNTL,
    +		     0, asi3out_text);
    +static const struct snd_kcontrol_new asi3out_control =
    +SOC_DAPM_ENUM("ASI3OUT Route", asi3out_enum);
    +static const char * const asibclk_text[] = {
    +	"DAC_CLK",
    +	"DAC_MOD_CLK",
    +	"ADC_CLK",
    +	"ADC_MOD_CLK",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi1bclk_enum, AIC3262_ASI1_BCLK_N_CNTL, 0, asibclk_text);
    +static const struct snd_kcontrol_new asi1bclk_control =
    +SOC_DAPM_ENUM("ASI1_BCLK Route", asi1bclk_enum);
    +
    +SOC_ENUM_SINGLE_DECL(asi2bclk_enum, AIC3262_ASI2_BCLK_N_CNTL, 0, asibclk_text);
    +static const struct snd_kcontrol_new asi2bclk_control =
    +SOC_DAPM_ENUM("ASI2_BCLK Route", asi2bclk_enum);
    +SOC_ENUM_SINGLE_DECL(asi3bclk_enum, AIC3262_ASI3_BCLK_N_CNTL, 0, asibclk_text);
    +static const struct snd_kcontrol_new asi3bclk_control =
    +SOC_DAPM_ENUM("ASI3_BCLK Route", asi3bclk_enum);
    +
    +static const char * const adc_mux_text[] = {
    +	"Analog",
    +	"Digital",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(adcl_enum, AIC3262_ADC_CHANNEL_POW, 4, adc_mux_text);
    +SOC_ENUM_SINGLE_DECL(adcr_enum, AIC3262_ADC_CHANNEL_POW, 2, adc_mux_text);
    +
    +static const struct snd_kcontrol_new adcl_mux =
    +SOC_DAPM_ENUM("Left ADC Route", adcl_enum);
    +
    +static const struct snd_kcontrol_new adcr_mux =
    +SOC_DAPM_ENUM("Right ADC Route", adcr_enum);
    +
    +/**
    + * aic326x_hp_event: - To handle headphone related task before and after
    + *			headphone powrup and power down
    + * @w: pointer variable to dapm_widget
    + * @kcontrol: mixer control
    + * @event: event element information
    + *
    + * Returns 0 for success.
    + */
    +static int aic326x_hp_event(struct snd_soc_dapm_widget *w,
    +			    struct snd_kcontrol *kcontrol, int event)
    +{
    +	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
    +	struct aic3262_priv *aic3262;
    +	int reg_mask = 0;
    +	int mute_reg = 0;
    +	int ret_wbits = 0;
    +	u8 hpl_hpr;
    +
    +	aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	if (w->shift == 1) {
    +		reg_mask = AIC3262_HPL_POWER_STATUS_MASK;
    +		mute_reg = AIC3262_HPL_VOL;
    +	}
    +	if (w->shift == 0) {
    +		reg_mask = AIC3262_HPR_POWER_STATUS_MASK;
    +		mute_reg = AIC3262_HPR_VOL;
    +	}
    +	switch (event) {
    +	case SND_SOC_DAPM_PRE_PMU:
    +			snd_soc_component_update_bits(codec, AIC3262_CHARGE_PUMP_CNTL,
    +					AIC3262_DYNAMIC_OFFSET_CALIB_MASK,
    +					AIC3262_DYNAMIC_OFFSET_CALIB);
    +			snd_soc_component_write(codec, mute_reg, 0x80);
    +			snd_soc_component_update_bits(codec, AIC3262_HP_CTL,
    +					AIC3262_HP_STAGE_MASK ,
    +					AIC3262_HP_STAGE_25 << AIC3262_HP_STAGE_SHIFT);
    +		break;
    +
    +	case SND_SOC_DAPM_POST_PMU:
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_HP_FLAG, reg_mask,
    +					      reg_mask, AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "HP POST_PMU timedout\n");
    +			return -1;
    +		}
    +		snd_soc_component_update_bits(codec, AIC3262_HP_CTL,
    +			AIC3262_HP_STAGE_MASK ,
    +			AIC3262_HP_STAGE_100 << AIC3262_HP_STAGE_SHIFT);
    +		break;
    +
    +	case SND_SOC_DAPM_PRE_PMD:
    +		snd_soc_component_update_bits(codec, AIC3262_HP_CTL,
    +				AIC3262_HP_STAGE_MASK ,
    +				AIC3262_HP_STAGE_25 << AIC3262_HP_STAGE_SHIFT);
    +		hpl_hpr = snd_soc_component_read(codec, AIC3262_HP_AMP_CNTL_R1);
    +		if((hpl_hpr & 0x3) == 0x3) {
    +			snd_soc_component_update_bits(codec, AIC3262_HP_AMP_CNTL_R1,
    +						AIC3262_HPL_POWER_MASK, 0x0);
    +			mdelay(1);
    +			snd_soc_component_update_bits(codec, AIC3262_HP_AMP_CNTL_R1,
    +						AIC3262_HPR_POWER_MASK, 0x0);
    +		}
    +		break;
    +
    +	case SND_SOC_DAPM_POST_PMD:
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_HP_FLAG, reg_mask, 0,
    +					      AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "HP POST_PMD timedout\n");
    +			return -1;
    +		}
    +		snd_soc_component_write(codec, mute_reg, 0xb9);
    +		snd_soc_component_write(codec, AIC3262_POWER_CONF,
    +				snd_soc_component_read(codec, AIC3262_POWER_CONF));
    +		break;
    +	default:
    +		BUG();
    +		return -EINVAL;
    +	}
    +	return 0;
    +}
    +
    +/**
    + *aic326x_dac_event: Headset popup reduction and powering up dsps together
    + *			when they are in sync mode
    + * @w: pointer variable to dapm_widget
    + * @kcontrol: pointer to sound control
    + * @event: event element information
    + *
    + * Returns 0 for success.
    + */
    +static int aic326x_dac_event(struct snd_soc_dapm_widget *w,
    +			     struct snd_kcontrol *kcontrol, int event)
    +{
    +	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
    +	int reg_mask = 0;
    +	int ret_wbits = 0;
    +	int run_state_mask;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	int sync_needed = 0, non_sync_state = 0;
    +	int other_dsp = 0, run_state = 0;
    +
    +	if (w->shift == 7) {
    +		reg_mask = AIC3262_LDAC_POWER_STATUS_MASK;
    +		run_state_mask = AIC3XXX_COPS_MDSP_D_L;
    +	}
    +	if (w->shift == 6) {
    +		reg_mask = AIC3262_RDAC_POWER_STATUS_MASK;
    +		run_state_mask = AIC3XXX_COPS_MDSP_D_R;
    +	}
    +	switch (event) {
    +	case SND_SOC_DAPM_POST_PMU:
    +
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_DAC_FLAG, reg_mask,
    +					      reg_mask, AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +
    +		sync_needed = aic3xxx_reg_read(aic3262->control_data,
    +							AIC3262_DAC_PRB);
    +		non_sync_state = dsp_non_sync_mode(aic3262->dsp_runstate);
    +		other_dsp = aic3262->dsp_runstate & AIC3XXX_COPS_MDSP_A;
    +
    +		if (sync_needed && non_sync_state && other_dsp) {
    +			run_state = aic3262_get_runstate(
    +						aic3262->codec);
    +			aic3262_dsp_pwrdwn_status(aic3262->codec);
    +			aic3262_dsp_pwrup(aic3262->codec, run_state);
    +		}
    +		aic3262->dsp_runstate |= run_state_mask;
    +
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "DAC POST_PMU timedout\n");
    +			return -1;
    +		}
    +		break;
    +	case SND_SOC_DAPM_POST_PMD:
    +
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_DAC_FLAG, reg_mask, 0,
    +					      AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +
    +		aic3262->dsp_runstate = (aic3262->dsp_runstate &
    +					 ~run_state_mask);
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "DAC POST_PMD timedout\n");
    +			return -1;
    +		}
    +		break;
    +	default:
    +		BUG();
    +		return -EINVAL;
    +	}
    +	return 0;
    +}
    +
    +/**
    + * aic326x_spk_event: Speaker related task before and after
    + *			 headphone powrup and power down$
    + * @w: pointer variable to dapm_widget,
    + * @kcontrolr: pointer variable to sound control,
    + * @event:	integer to event,
    + *
    + * Return value: 0 for success
    + */
    +static int aic326x_spk_event(struct snd_soc_dapm_widget *w,
    +			     struct snd_kcontrol *kcontrol, int event)
    +{
    +	int reg_mask;
    +
    +	if (w->shift == 1)
    +		reg_mask = AIC3262_SPKL_POWER_STATUS_MASK;
    +	if (w->shift == 0)
    +		reg_mask = AIC3262_SPKR_POWER_STATUS_MASK;
    +	switch (event) {
    +	case SND_SOC_DAPM_POST_PMU:
    +		mdelay(1);
    +		break;
    +	case SND_SOC_DAPM_POST_PMD:
    +		mdelay(1);
    +		break;
    +	default:
    +		BUG();
    +		return -EINVAL;
    +	}
    +	return 0;
    +}
    +
    +/**$
    + * pll_power_on_event: provide delay after widget  power up
    + * @w:  pointer variable to dapm_widget,
    + * @kcontrolr: pointer variable to sound control,
    + * @event:	integer to event,
    + *
    + * Return value: 0 for success
    + */
    +static int pll_power_on_event(struct snd_soc_dapm_widget *w,
    +			      struct snd_kcontrol *kcontrol, int event)
    +{
    +	if (event == SND_SOC_DAPM_POST_PMU)
    +		mdelay(10);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_set_mode_get: To get different mode of Firmware through tinymix
    + * @kcontrolr: pointer to sound control,
    + * ucontrol: pointer to control element value,
    + *
    + * Return value: 0 for success
    + */
    +static int aic3262_set_mode_get(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
    +	struct aic3262_priv *priv_ds = snd_soc_component_get_drvdata(codec);
    +
    +	ucontrol->value.integer.value[0] = ((priv_ds->cfw_p->cur_mode << 8)
    +					    | priv_ds->cfw_p->cur_cfg);
    +
    +	return 0;
    +}
    +
    +/**
    + * aic3262_set_mode_put: To set different mode of Firmware through tinymix
    + * @kcontrolr: pointer to sound control,
    + * ucontrol: pointer to control element value,
    + *
    + * Return value: 0 for success
    + */
    +static int aic3262_set_mode_put(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
    +	struct aic3262_priv *priv_ds = snd_soc_component_get_drvdata(codec);
    +
    +	int next_mode = 0, next_cfg = 0;
    +	int ret = 0;
    +
    +	next_mode = (ucontrol->value.integer.value[0] >> 8);
    +	next_cfg = (ucontrol->value.integer.value[0]) & 0xFF;
    +	if (priv_ds == NULL)
    +		dev_err(codec->dev, "failed to load firmware\n");
    +	else
    +		ret = aic3xxx_cfw_setmode_cfg(priv_ds->cfw_p,
    +					      next_mode, next_cfg);
    +	return ret;
    +}
    +
    +/**
    + * aic326x_adc_dsp_event: To get DSP run state to perform synchronization
    + * @w: pointer variable to dapm_widget
    + * @kcontrol: pointer to sound control
    + * @event: event element information
    + *
    + * Returns 0 for success.
    + */
    +static int aic326x_adc_dsp_event(struct snd_soc_dapm_widget *w,
    +				 struct snd_kcontrol *kcontrol, int event)
    +{
    +	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
    +	int run_state = 0;
    +	int non_sync_state = 0, sync_needed = 0;
    +	int other_dsp = 0;
    +	int run_state_mask = 0;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	int reg_mask = 0;
    +	int ret_wbits = 0;
    +
    +	if (w->shift == 7) {
    +		reg_mask = AIC3262_LADC_POWER_MASK;
    +		run_state_mask = AIC3XXX_COPS_MDSP_A_L;
    +	}
    +	if (w->shift == 6) {
    +		reg_mask = AIC3262_RADC_POWER_MASK;
    +		run_state_mask = AIC3XXX_COPS_MDSP_A_R;
    +	}
    +	switch (event) {
    +	case SND_SOC_DAPM_POST_PMU:
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_ADC_FLAG, reg_mask,
    +					      reg_mask, AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +		sync_needed =  aic3xxx_reg_read(aic3262->control_data,
    +							AIC3262_DAC_PRB);
    +		non_sync_state = dsp_non_sync_mode(aic3262->dsp_runstate);
    +		other_dsp = aic3262->dsp_runstate & AIC3XXX_COPS_MDSP_D;
    +		if (sync_needed && non_sync_state && other_dsp) {
    +			run_state = aic3262_get_runstate(
    +						aic3262->codec);
    +			aic3262_dsp_pwrdwn_status(aic3262->codec);
    +			aic3262_dsp_pwrup(aic3262->codec, run_state);
    +		}
    +		aic3262->dsp_runstate |= run_state_mask;
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "ADC POST_PMU timedout\n");
    +			return -1;
    +		}
    +		break;
    +	case SND_SOC_DAPM_POST_PMD:
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_ADC_FLAG, reg_mask, 0,
    +					      AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +		aic3262->dsp_runstate = (aic3262->dsp_runstate &
    +					 ~run_state_mask);
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "ADC POST_PMD timedout\n");
    +			return -1;
    +		}
    +		break;
    +	default:
    +		BUG();
    +		return -EINVAL;
    +	}
    +	return 0;
    +}
    +
    +static const struct snd_soc_dapm_widget aic3262_dapm_widgets[] = {
    +    /* TODO: Can we switch these off ? */
    +    SND_SOC_DAPM_AIF_IN("DIN1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
    +    SND_SOC_DAPM_AIF_IN("DIN2", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0),
    +    SND_SOC_DAPM_AIF_IN("DIN3", "ASI3 Playback", 0, SND_SOC_NOPM, 0, 0),
    +
    +    SND_SOC_DAPM_DAC_E("Left DAC", NULL, AIC3262_PASI_DAC_DP_SETUP, 7, 0,
    +		       aic326x_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +    SND_SOC_DAPM_DAC_E("Right DAC", NULL, AIC3262_PASI_DAC_DP_SETUP, 6, 0,
    +		       aic326x_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +
    +    /* dapm widget (path domain) for HPL Output Mixer */
    +    SND_SOC_DAPM_MIXER("HP Left Mixer", SND_SOC_NOPM, 0, 0,
    +		       &hpl_output_mixer_controls[0],
    +		       ARRAY_SIZE(hpl_output_mixer_controls)),
    +
    +    /* dapm widget (path domain) for HPR Output Mixer */
    +    SND_SOC_DAPM_MIXER("HP Right Mixer", SND_SOC_NOPM, 0, 0,
    +		       &hpr_output_mixer_controls[0],
    +		       ARRAY_SIZE(hpr_output_mixer_controls)),
    +
    +    SND_SOC_DAPM_PGA_S("HP Left Playback Driver", 3,
    +		       AIC3262_HP_AMP_CNTL_R1, 1, 0, aic326x_hp_event,
    +		       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +    SND_SOC_DAPM_PGA_S("HP Right Playback Driver", 3,
    +		       AIC3262_HP_AMP_CNTL_R1, 0, 0, aic326x_hp_event,
    +		       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +
    +    /* dapm widget (path domain) for LOL Output Mixer */
    +    SND_SOC_DAPM_MIXER("LO Left Mixer", SND_SOC_NOPM, 0, 0,
    +		       &lol_output_mixer_controls[0],
    +		       ARRAY_SIZE(lol_output_mixer_controls)),
    +
    +    /* dapm widget (path domain) for LOR Output Mixer mixer */
    +    SND_SOC_DAPM_MIXER("LO Right Mixer", SND_SOC_NOPM, 0, 0,
    +		       &lor_output_mixer_controls[0],
    +		       ARRAY_SIZE(lor_output_mixer_controls)),
    +
    +    SND_SOC_DAPM_PGA_S("LO Left Playback Driver", 2,
    +		       AIC3262_LINE_AMP_CNTL_R1, 1, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA_S("LO Right Playback Driver", 2,
    +		       AIC3262_LINE_AMP_CNTL_R1, 0, 0, NULL, 0),
    +
    +    /* dapm widget (path domain) for SPKL Output Mixer */
    +    SND_SOC_DAPM_MIXER("SPK Left Mixer", SND_SOC_NOPM, 0, 0,
    +		       &spkl_output_mixer_controls[0],
    +		       ARRAY_SIZE(spkl_output_mixer_controls)),
    +
    +    /* dapm widget (path domain) for SPKR Output Mixer */
    +    SND_SOC_DAPM_MIXER("SPK Right Mixer", SND_SOC_NOPM, 0, 0,
    +		       &spkr_output_mixer_controls[0],
    +		       ARRAY_SIZE(spkr_output_mixer_controls)),
    +
    +    SND_SOC_DAPM_PGA_S("SPK Left Playback Driver", 3,
    +		       AIC3262_SPK_AMP_CNTL_R1, 1, 0, aic326x_spk_event,
    +		       SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
    +    SND_SOC_DAPM_PGA_S("SPK Right Playback Driver", 3,
    +		       AIC3262_SPK_AMP_CNTL_R1, 0, 0, aic326x_spk_event,
    +		       SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
    +
    +    /* dapm widget (path domain) for SPKR Output Mixer */
    +    SND_SOC_DAPM_MIXER("REC Mixer", SND_SOC_NOPM, 0, 0,
    +		       &rec_output_mixer_controls[0],
    +		       ARRAY_SIZE(rec_output_mixer_controls)),
    +
    +    SND_SOC_DAPM_PGA_S("RECP Playback Driver", 3, AIC3262_REC_AMP_CNTL_R5,
    +		       7, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA_S("RECM Playback Driver", 3, AIC3262_REC_AMP_CNTL_R5,
    +		       6, 0, NULL, 0),
    +
    +    SND_SOC_DAPM_MUX("ASI1LIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi1lin_control),
    +    SND_SOC_DAPM_MUX("ASI1RIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi1rin_control),
    +    SND_SOC_DAPM_MUX("ASI2LIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi2lin_control),
    +    SND_SOC_DAPM_MUX("ASI2RIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi2rin_control),
    +    SND_SOC_DAPM_MUX("ASI3LIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi3lin_control),
    +    SND_SOC_DAPM_MUX("ASI3RIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi3rin_control),
    +
    +    SND_SOC_DAPM_PGA("ASI1LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI1RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI1MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    /* TODO: Can we switch the ASIxIN off? */
    +    SND_SOC_DAPM_PGA("ASI1IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
    +
    +    SND_SOC_DAPM_MUX("DAC MiniDSP IN1 Route",
    +		     SND_SOC_NOPM, 0, 0, &dacminidspin1_control),
    +    SND_SOC_DAPM_MUX("DAC MiniDSP IN2 Route",
    +		     SND_SOC_NOPM, 0, 0, &dacminidspin2_control),
    +    SND_SOC_DAPM_MUX("DAC MiniDSP IN3 Route",
    +		     SND_SOC_NOPM, 0, 0, &dacminidspin3_control),
    +
    +    SND_SOC_DAPM_MUX("ADC DAC Route",
    +		     SND_SOC_NOPM, 0, 0, &adcdacroute_control),
    +
    +    SND_SOC_DAPM_PGA("CM", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("CM1 Left Capture", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("CM2 Left Capture", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("CM1 Right Capture", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("CM2 Right Capture", SND_SOC_NOPM, 0, 0, NULL, 0),
    +
    +    /* TODO: Can we switch these off ? */
    +    SND_SOC_DAPM_AIF_OUT("DOUT1", "ASI1 Capture", 0, SND_SOC_NOPM, 0, 0),
    +    SND_SOC_DAPM_AIF_OUT("DOUT2", "ASI2 Capture", 0, SND_SOC_NOPM, 0, 0),
    +    SND_SOC_DAPM_AIF_OUT("DOUT3", "ASI3 Capture", 0, SND_SOC_NOPM, 0, 0),
    +
    +    SND_SOC_DAPM_MUX("DOUT1 Route",
    +		     SND_SOC_NOPM, 0, 0, &dout1_control),
    +    SND_SOC_DAPM_MUX("DOUT2 Route",
    +		     SND_SOC_NOPM, 0, 0, &dout2_control),
    +    SND_SOC_DAPM_MUX("DOUT3 Route",
    +		     SND_SOC_NOPM, 0, 0, &dout3_control),
    +
    +    SND_SOC_DAPM_PGA("ASI1OUT", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2OUT", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3OUT", SND_SOC_NOPM, 0, 0, NULL, 0),
    +
    +    SND_SOC_DAPM_MUX("ASI1OUT Route",
    +		     SND_SOC_NOPM, 0, 0, &asi1out_control),
    +    SND_SOC_DAPM_MUX("ASI2OUT Route",
    +		     SND_SOC_NOPM, 0, 0, &asi2out_control),
    +    SND_SOC_DAPM_MUX("ASI3OUT Route",
    +		     SND_SOC_NOPM, 0, 0, &asi3out_control),
    +
    +    /* TODO: Can we switch the ASI1 OUT1 off? */
    +    /* TODO: Can we switch them off? */
    +    SND_SOC_DAPM_PGA("ADC MiniDSP OUT1", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ADC MiniDSP OUT2", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ADC MiniDSP OUT3", SND_SOC_NOPM, 0, 0, NULL, 0),
    +
    +    SND_SOC_DAPM_MUX("Left ADC Route", SND_SOC_NOPM, 0, 0, &adcl_mux),
    +    SND_SOC_DAPM_MUX("Right ADC Route", SND_SOC_NOPM, 0, 0, &adcr_mux),
    +
    +    SND_SOC_DAPM_ADC_E("Left ADC", NULL, AIC3262_ADC_CHANNEL_POW, 7, 0,
    +		       aic326x_adc_dsp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +    SND_SOC_DAPM_ADC_E("Right ADC", NULL, AIC3262_ADC_CHANNEL_POW, 6, 0,
    +		       aic326x_adc_dsp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +
    +    SND_SOC_DAPM_PGA_S("Left MicPGA", 0, AIC3262_MICL_PGA, 7, 1, NULL, 0),
    +    SND_SOC_DAPM_PGA_S("Right MicPGA", 0, AIC3262_MICR_PGA, 7, 1, NULL, 0),
    +
    +    SND_SOC_DAPM_PGA_S("MA Left Playback PGA", 1, AIC3262_MA_CNTL,
    +		       3, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA_S("MA Right Playback PGA", 1, AIC3262_MA_CNTL,
    +		       2, 0, NULL, 0),
    +
    +    /* dapm widget for MAL PGA Mixer */
    +    SND_SOC_DAPM_MIXER("MA Left PGA Mixer", SND_SOC_NOPM, 0, 0,
    +		       &mal_pga_mixer_controls[0],
    +		       ARRAY_SIZE(mal_pga_mixer_controls)),
    +
    +    /* dapm widget for MAR PGA Mixer */
    +    SND_SOC_DAPM_MIXER("MA Right PGA Mixer", SND_SOC_NOPM, 0, 0,
    +		       &mar_pga_mixer_controls[0],
    +		       ARRAY_SIZE(mar_pga_mixer_controls)),
    +
    +    /* dapm widget for Left Input Mixer */
    +    SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
    +		       &left_input_mixer_controls[0],
    +		       ARRAY_SIZE(left_input_mixer_controls)),
    +
    +    /* dapm widget for Right Input Mixer */
    +    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_OUTPUT("HP Left Playback"),
    +    SND_SOC_DAPM_OUTPUT("HP Right Playback"),
    +    SND_SOC_DAPM_OUTPUT("LO Left Playback"),
    +    SND_SOC_DAPM_OUTPUT("LO Right Playback"),
    +    SND_SOC_DAPM_OUTPUT("SPK Left Playback"),
    +    SND_SOC_DAPM_OUTPUT("SPK Right Playback"),
    +    SND_SOC_DAPM_OUTPUT("RECP Playback"),
    +    SND_SOC_DAPM_OUTPUT("RECM Playback"),
    +
    +    SND_SOC_DAPM_INPUT("IN1 Left Capture"),
    +    SND_SOC_DAPM_INPUT("IN2 Left Capture"),
    +    SND_SOC_DAPM_INPUT("IN3 Left Capture"),
    +    SND_SOC_DAPM_INPUT("IN4 Left Capture"),
    +    SND_SOC_DAPM_INPUT("IN1 Right Capture"),
    +    SND_SOC_DAPM_INPUT("IN2 Right Capture"),
    +    SND_SOC_DAPM_INPUT("IN3 Right Capture"),
    +    SND_SOC_DAPM_INPUT("IN4 Right Capture"),
    +    SND_SOC_DAPM_INPUT("Left DMIC Capture"),
    +    SND_SOC_DAPM_INPUT("Right DMIC Capture"),
    +
    +    SND_SOC_DAPM_MICBIAS("Mic Bias Ext", AIC3262_MIC_BIAS_CNTL, 6, 0),
    +    SND_SOC_DAPM_MICBIAS("Mic Bias Int", AIC3262_MIC_BIAS_CNTL, 2, 0),
    +
    +    SND_SOC_DAPM_SUPPLY_S("PLLCLK", 0, AIC3262_PLL_PR_POW_REG, 7, 0,
    +			  pll_power_on_event, SND_SOC_DAPM_POST_PMU),
    +    SND_SOC_DAPM_SUPPLY_S("DACCLK", 2, AIC3262_NDAC_DIV_POW_REG, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("CODEC_CLK_IN", 1, SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("DAC_MOD_CLK", 3, AIC3262_MDAC_DIV_POW_REG,
    +			  7, 0, NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ADCCLK", 2, AIC3262_NADC_DIV_POW_REG, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ADC_MOD_CLK", 3, AIC3262_MADC_DIV_POW_REG,
    +			  7, 0, NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI1_BCLK", 4, AIC3262_ASI1_BCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI1_WCLK", 4, AIC3262_ASI1_WCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI2_BCLK", 4, AIC3262_ASI2_BCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI2_WCLK", 4, AIC3262_ASI2_WCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI3_BCLK", 4, AIC3262_ASI3_BCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI3_WCLK", 4, AIC3262_ASI3_WCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_MUX("ASI1_BCLK Route",
    +		     SND_SOC_NOPM, 0, 0, &asi1bclk_control),
    +    SND_SOC_DAPM_MUX("ASI2_BCLK Route",
    +		     SND_SOC_NOPM, 0, 0, &asi2bclk_control),
    +    SND_SOC_DAPM_MUX("ASI3_BCLK Route",
    +		     SND_SOC_NOPM, 0, 0, &asi3bclk_control),
    +};
    +
    +static const struct snd_soc_dapm_route aic3262_dapm_routes[] = {
    +	/* TODO: Do we need only DACCLK for ASIIN's and ADCCLK for ASIOUT??? */
    +	/* Clock portion */
    +	{"CODEC_CLK_IN", NULL, "PLLCLK"},
    +	{"DACCLK", NULL, "CODEC_CLK_IN"},
    +	{"ADCCLK", NULL, "CODEC_CLK_IN"},
    +	{"DAC_MOD_CLK", NULL, "DACCLK"},
    +#ifdef AIC3262_SYNC_MODE
    +	{"ADC_MOD_CLK", NULL, "DACCLK"},
    +#else
    +	{"ADC_MOD_CLK", NULL, "ADCCLK"},
    +#endif
    +	{"ASI1_BCLK Route", NULL /*"DAC_CLK"*/, "DACCLK"},
    +	{"ASI1_BCLK Route", NULL /*/"DAC_MOD_CLK"*/, "DAC_MOD_CLK"},
    +	{"ASI1_BCLK Route", NULL /*"ADC_CLK"*/, "ADCCLK"},
    +	{"ASI1_BCLK Route", NULL /*"ADC_MOD_CLK"*/, "ADC_MOD_CLK"},
    +
    +	{"ASI2_BCLK Route", NULL /*"DAC_CLK"*/, "DACCLK"},
    +	{"ASI2_BCLK Route", NULL /*/"DAC_MOD_CLK"*/, "DAC_MOD_CLK"},
    +	{"ASI2_BCLK Route", NULL /*"ADC_CLK"*/, "ADCCLK"},
    +	{"ASI2_BCLK Route", NULL /*"ADC_MOD_CLK"*/, "ADC_MOD_CLK"},
    +
    +	{"ASI3_BCLK Route", NULL /*"DAC_CLK"*/, "DACCLK"},
    +	{"ASI3_BCLK Route", NULL /*/"DAC_MOD_CLK"*/, "DAC_MOD_CLK"},
    +	{"ASI3_BCLK Route", NULL /*"ADC_CLK"*/, "ADCCLK"},
    +	{"ASI3_BCLK Route", NULL /*"ADC_MOD_CLK"*/, "ADC_MOD_CLK"},
    +
    +#ifdef AIC3262_ASI1_MASTER
    +	{"DIN1", NULL, "ASI1_BCLK Route"},
    +	{"DOUT1", NULL, "ASI1_BCLK Route"},
    +	{"DIN1", NULL, "ASI1_WCLK"},
    +	{"DOUT1", NULL, "ASI1_WCLK"},
    +	{"DIN1", NULL, "ASI1_BCLK"},
    +	{"DOUT1", NULL, "ASI1_BCLK"},
    +#endif
    +
    +#ifdef AIC3262_ASI2_MASTER
    +	{"DIN2", NULL, "ASI2_BCLK Route"},
    +	{"DOUT2", NULL, "ASI2_BCLK Route"},
    +	{"DIN2", NULL, "ASI2_WCLK"},
    +	{"DOUT2", NULL, "ASI2_WCLK"},
    +	{"DIN2", NULL, "ASI2_BCLK"},
    +	{"DOUT2", NULL, "ASI2_BCLK"},
    +#endif
    +#ifdef AIC3262_ASI3_MASTER
    +	{"DIN3", NULL, "ASI3_BCLK"},
    +	{"DOUT3", NULL, "ASI3_BCLK"},
    +	{"DIN3", NULL, "ASI3_BCLK Route"},
    +	{"DOUT3", NULL, "ASI3_BCLK Route"},
    +	{"DIN3", NULL, "ASI3_WCLK"},
    +	{"DOUT3", NULL, "ASI3_WCLK"},
    +#endif
    +	{"Left DAC", NULL, "DAC_MOD_CLK"},
    +	{"Right DAC", NULL, "DAC_MOD_CLK"},
    +	/* When we are master, ASI bclk and wclk are generated by
    +	* DAC_MOD_CLK, so we put them as dependency for ADC too.
    +	*/
    +	{"Left ADC", NULL, "DAC_MOD_CLK"},
    +	{"Right ADC", NULL, "DAC_MOD_CLK"},
    +	{"Left ADC", NULL, "ADC_MOD_CLK"},
    +	{"Right ADC", NULL, "ADC_MOD_CLK"},
    +	/* Playback (DAC) Portion */
    +	{"HP Left Mixer", "Left DAC Playback Switch", "Left DAC"},
    +	{"HP Left Mixer", "MA Left Playback Switch", "MA Left Playback PGA"},
    +	{"HP Left Mixer", "LO Left-B1 Playback Volume", "LO Left Playback"},
    +
    +	{"HP Right Mixer", "LO Right-B1 Playback Volume", "LO Right Playback"},
    +	{"HP Right Mixer", "Left DAC Playback Switch", "Left DAC"},
    +	{"HP Right Mixer", "Right DAC Playback Switch", "Right DAC"},
    +	{"HP Right Mixer", "MA Right Playback Switch", "MA Right Playback PGA"},
    +
    +	{"HP Left Playback Driver", NULL, "HP Left Mixer"},
    +	{"HP Right Playback Driver", NULL, "HP Right Mixer"},
    +
    +	{"HP Left Playback", NULL, "HP Left Playback Driver"},
    +	{"HP Right Playback", NULL, "HP Right Playback Driver"},
    +
    +	{"LO Left Mixer", "MA Left Playback Switch", "MA Left Playback PGA"},
    +	{"LO Left Mixer", "IN1 Left-B Capture Switch", "IN1 Left Capture"},
    +	{"LO Left Mixer", "Left DAC Playback Switch", "Left DAC"},
    +	{"LO Left Mixer", "Right DAC Playback Switch", "Right DAC"},
    +
    +	{"LO Right Mixer", "LO Left Playback Switch", "LO Left Playback"},
    +	{"LO Right Mixer", "Right DAC Playback Switch", "Right DAC"},
    +	{"LO Right Mixer", "MA Right Playback Switch", "MA Right Playback PGA"},
    +	{"LO Right Mixer", "IN1 Right-B Capture Switch", "IN1 Right Capture"},
    +
    +	{"LO Left Playback Driver", NULL, "LO Left Mixer"},
    +	{"LO Right Playback Driver", NULL, "LO Right Mixer"},
    +
    +	{"LO Left Playback", NULL, "LO Left Playback Driver"},
    +	{"LO Right Playback", NULL, "LO Right Playback Driver"},
    +
    +	{"REC Mixer", "LO Left-B2 Playback Volume", "LO Left Playback"},
    +	{"REC Mixer", "IN1 Left Capture Volume", "IN1 Left Capture"},
    +	{"REC Mixer", "IN1 Right Capture Volume", "IN1 Right Capture"},
    +	{"REC Mixer", "LO Right-B2 Playback Volume", "LO Right Playback"},
    +
    +	{"RECP Playback Driver", NULL, "REC Mixer"},
    +	{"RECM Playback Driver", NULL, "REC Mixer"},
    +
    +	{"RECP Playback", NULL, "RECP Playback Driver"},
    +	{"RECM Playback", NULL, "RECM Playback Driver"},
    +
    +	{"SPK Left Mixer", "MA Left Playback Switch", "MA Left Playback PGA"},
    +	{"SPK Left Mixer", "LO Left Playback Volume", "LO Left Playback"},
    +	{"SPK Left Mixer", "SPR_IN Switch", "SPK Right Mixer"},
    +
    +	{"SPK Right Mixer", "LO Right Playback Volume", "LO Right Playback"},
    +	{"SPK Right Mixer", "MA Right Playback Switch", "MA Right Playback PGA"},
    +
    +	{"SPK Left Playback Driver", NULL, "SPK Left Mixer"},
    +	{"SPK Right Playback Driver", NULL, "SPK Right Mixer"},
    +
    +	{"SPK Left Playback", NULL, "SPK Left Playback Driver"},
    +	{"SPK Right Playback", NULL, "SPK Right Playback Driver"},
    +	/* ASI Input routing */
    +	{"ASI1LIN", NULL, "DIN1"},
    +	{"ASI1RIN", NULL, "DIN1"},
    +	{"ASI1MonoMixIN", NULL, "DIN1"},
    +	{"ASI2LIN", NULL, "DIN2"},
    +	{"ASI2RIN", NULL, "DIN2"},
    +	{"ASI2MonoMixIN", NULL, "DIN2"},
    +	{"ASI3LIN", NULL, "DIN3"},
    +	{"ASI3RIN", NULL, "DIN3"},
    +	{"ASI3MonoMixIN", NULL, "DIN3"},
    +
    +	{"ASI1LIN Route", "ASI1 Left In", "ASI1LIN"},
    +	{"ASI1LIN Route", "ASI1 Right In", "ASI1RIN"},
    +	{"ASI1LIN Route", "ASI1 MonoMix In", "ASI1MonoMixIN"},
    +
    +	{"ASI1RIN Route", "ASI1 Right In", "ASI1RIN"},
    +	{"ASI1RIN Route", "ASI1 Left In", "ASI1LIN"},
    +	{"ASI1RIN Route", "ASI1 MonoMix In", "ASI1MonoMixIN"},
    +
    +	{"ASI2LIN Route", "ASI2 Left In", "ASI2LIN"},
    +	{"ASI2LIN Route", "ASI2 Right In", "ASI2RIN"},
    +	{"ASI2LIN Route", "ASI2 MonoMix In", "ASI2MonoMixIN"},
    +
    +	{"ASI2RIN Route", "ASI2 Right In", "ASI2RIN"},
    +	{"ASI2RIN Route", "ASI2 Left In", "ASI2LIN"},
    +	{"ASI2RIN Route", "ASI2 MonoMix In", "ASI2MonoMixIN"},
    +
    +	{"ASI3LIN Route", "ASI3 Left In", "ASI3LIN"},
    +	{"ASI3LIN Route", "ASI3 Right In", "ASI3RIN"},
    +	{"ASI3LIN Route", "ASI3 MonoMix In", "ASI3MonoMixIN"},
    +
    +	{"ASI3RIN Route", "ASI3 Right In", "ASI3RIN"},
    +	{"ASI3RIN Route", "ASI3 Left In", "ASI3LIN"},
    +	{"ASI3RIN Route", "ASI3 MonoMix In", "ASI3MonoMixIN"},
    +
    +	{"ASI1IN Port", NULL, "ASI1LIN Route"},
    +	{"ASI1IN Port", NULL, "ASI1RIN Route"},
    +	{"ASI2IN Port", NULL, "ASI2LIN Route"},
    +	{"ASI2IN Port", NULL, "ASI2RIN Route"},
    +	{"ASI3IN Port", NULL, "ASI3LIN Route"},
    +	{"ASI3IN Port", NULL, "ASI3RIN Route"},
    +
    +	{"DAC MiniDSP IN1 Route", "ASI1 In", "ASI1IN Port"},
    +	{"DAC MiniDSP IN1 Route", "ASI2 In", "ASI2IN Port"},
    +	{"DAC MiniDSP IN1 Route", "ASI3 In", "ASI3IN Port"},
    +	{"DAC MiniDSP IN1 Route", "ADC MiniDSP Out", "ADC MiniDSP OUT1"},
    +
    +	{"DAC MiniDSP IN2 Route", "ASI1 In", "ASI1IN Port"},
    +	{"DAC MiniDSP IN2 Route", "ASI2 In", "ASI2IN Port"},
    +	{"DAC MiniDSP IN2 Route", "ASI3 In", "ASI3IN Port"},
    +
    +	{"DAC MiniDSP IN3 Route", "ASI1 In", "ASI1IN Port"},
    +	{"DAC MiniDSP IN3 Route", "ASI2 In", "ASI2IN Port"},
    +	{"DAC MiniDSP IN3 Route", "ASI3 In", "ASI3IN Port"},
    +
    +	{"Left DAC", NULL, "DAC MiniDSP IN1 Route"},
    +	{"Right DAC", NULL, "DAC MiniDSP IN1 Route"},
    +	{"Left DAC", NULL, "DAC MiniDSP IN2 Route"},
    +	{"Right DAC", NULL, "DAC MiniDSP IN2 Route"},
    +	{"Left DAC", NULL, "DAC MiniDSP IN3 Route"},
    +	{"Right DAC", NULL, "DAC MiniDSP IN3 Route"},
    +
    +	/* Mixer Amplifier */
    +	{"MA Left PGA Mixer", "IN1 Left Capture Switch", "IN1 Left Capture"},
    +	{"MA Left PGA Mixer", "Left MicPGA Volume", "Left MicPGA"},
    +
    +	{"MA Left Playback PGA", NULL, "MA Left PGA Mixer"},
    +
    +	{"MA Right PGA Mixer", "IN1 Right Capture Switch", "IN1 Right Capture"},
    +	{"MA Right PGA Mixer", "Right MicPGA Volume", "Right MicPGA"},
    +
    +	{"MA Right Playback PGA", NULL, "MA Right PGA Mixer"},
    +
    +	/* Virtual connection between DAC and ADC for miniDSP IPC */
    +	{"ADC DAC Route", "On", "Left ADC"},
    +	{"ADC DAC Route", "On", "Right ADC"},
    +
    +	{"Left DAC", NULL, "ADC DAC Route"},
    +	{"Right DAC", NULL, "ADC DAC Route"},
    +
    +	/* Capture (ADC) portions */
    +	/* Left Positive PGA input */
    +	{"Left Input Mixer", "IN1 Left Capture Switch", "IN1 Left Capture"},
    +	{"Left Input Mixer", "IN2 Left Capture Switch", "IN2 Left Capture"},
    +	{"Left Input Mixer", "IN3 Left Capture Switch", "IN3 Left Capture"},
    +	{"Left Input Mixer", "IN4 Left Capture Switch", "IN4 Left Capture"},
    +	{"Left Input Mixer", "IN1 Right Capture Switch", "IN1 Right Capture"},
    +	/* Left Negative PGA input */
    +	{"Left Input Mixer", "IN2 Right Capture Switch", "IN2 Right Capture"},
    +	{"Left Input Mixer", "IN3 Right Capture Switch", "IN3 Right Capture"},
    +	{"Left Input Mixer", "IN4 Right Capture Switch", "IN4 Right Capture"},
    +	{"Left Input Mixer", "CM2 Left Capture Switch", "CM2 Left Capture"},
    +	{"Left Input Mixer", "CM1 Left Capture Switch", "CM1 Left Capture"},
    +
    +	/* Right Positive PGA Input */
    +	{"Right Input Mixer", "IN1 Right Capture Switch", "IN1 Right Capture"},
    +	{"Right Input Mixer", "IN2 Right Capture Switch", "IN2 Right Capture"},
    +	{"Right Input Mixer", "IN3 Right Capture Switch", "IN3 Right Capture"},
    +	{"Right Input Mixer", "IN4 Right Capture Switch", "IN4 Right Capture"},
    +	{"Right Input Mixer", "IN2 Left Capture Switch", "IN2 Left Capture"},
    +	/* Right Negative PGA Input */
    +	{"Right Input Mixer", "IN1 Left Capture Switch", "IN1 Left Capture"},
    +	{"Right Input Mixer", "IN3 Left Capture Switch", "IN3 Left Capture"},
    +	{"Right Input Mixer", "IN4 Left Capture Switch", "IN4 Left Capture"},
    +	{"Right Input Mixer", "CM1 Right Capture Switch", "CM1 Right Capture"},
    +	{"Right Input Mixer", "CM2 Right Capture Switch", "CM2 Right Capture"},
    +
    +	{"CM1 Left Capture", NULL, "CM"},
    +	{"CM2 Left Capture", NULL, "CM"},
    +	{"CM1 Right Capture", NULL, "CM"},
    +	{"CM2 Right Capture", NULL, "CM"},
    +
    +	{"Left MicPGA", NULL, "Left Input Mixer"},
    +	{"Right MicPGA", NULL, "Right Input Mixer"},
    +
    +	{"Left ADC Route", "Analog", "Left MicPGA"},
    +	{"Left ADC Route", "Digital", "Left DMIC Capture"},
    +
    +	{"Right ADC Route", "Analog", "Right MicPGA"},
    +	{"Right ADC Route", "Digital", "Right DMIC Capture"},
    +
    +	{"Left ADC", NULL, "Left ADC Route"},
    +	{"Right ADC", NULL, "Right ADC Route"},
    +
    +	/* ASI Output Routing */
    +	{"ADC MiniDSP OUT1", NULL, "Left ADC"},
    +	{"ADC MiniDSP OUT1", NULL, "Right ADC"},
    +	{"ADC MiniDSP OUT2", NULL, "Left ADC"},
    +	{"ADC MiniDSP OUT2", NULL, "Right ADC"},
    +	{"ADC MiniDSP OUT3", NULL, "Left ADC"},
    +	{"ADC MiniDSP OUT3", NULL, "Right ADC"},
    +
    +	{"ASI1OUT Route", "ADC MiniDSP Out1", "ADC MiniDSP OUT1"},
    +	{"ASI1OUT Route", "ASI1In Bypass", "ASI1IN Port"},
    +	{"ASI1OUT Route", "ASI2In Bypass", "ASI2IN Port"},
    +	{"ASI1OUT Route", "ASI3In Bypass", "ASI3IN Port"},
    +
    +	{"ASI2OUT Route", "ADC MiniDSP Out1", "ADC MiniDSP OUT1"},
    +	{"ASI2OUT Route", "ASI1In Bypass", "ASI1IN Port"},
    +	{"ASI2OUT Route", "ASI2In Bypass", "ASI2IN Port"},
    +	{"ASI2OUT Route", "ASI3In Bypass", "ASI3IN Port"},
    +	{"ASI2OUT Route", "ADC MiniDSP Out2", "ADC MiniDSP OUT2"},
    +
    +	{"ASI3OUT Route", "ADC MiniDSP Out1", "ADC MiniDSP OUT1"},
    +	{"ASI3OUT Route", "ASI1In Bypass", "ASI1IN Port"},
    +	{"ASI3OUT Route", "ASI2In Bypass", "ASI2IN Port"},
    +	{"ASI3OUT Route", "ASI3In Bypass", "ASI3IN Port"},
    +	{"ASI3OUT Route", "ADC MiniDSP Out3", "ADC MiniDSP OUT3"},
    +
    +	{"ASI1OUT", NULL, "ASI1OUT Route"},
    +	{"ASI2OUT", NULL, "ASI2OUT Route"},
    +	{"ASI3OUT", NULL, "ASI3OUT Route"},
    +
    +	{"DOUT1 Route", "ASI1 Out", "ASI1OUT"},
    +	{"DOUT1 Route", "DIN1 Bypass", "DIN1"},
    +	{"DOUT1 Route", "DIN2 Bypass", "DIN2"},
    +	{"DOUT1 Route", "DIN3 Bypass", "DIN3"},
    +
    +	{"DOUT2 Route", "ASI2 Out", "ASI2OUT"},
    +	{"DOUT2 Route", "DIN1 Bypass", "DIN1"},
    +	{"DOUT2 Route", "DIN2 Bypass", "DIN2"},
    +	{"DOUT2 Route", "DIN3 Bypass", "DIN3"},
    +
    +	{"DOUT3 Route", "ASI3 Out", "ASI3OUT"},
    +	{"DOUT3 Route", "DIN1 Bypass", "DIN1"},
    +	{"DOUT3 Route", "DIN2 Bypass", "DIN2"},
    +	{"DOUT3 Route", "DIN3 Bypass", "DIN3"},
    +
    +	{"DOUT1", NULL, "DOUT1 Route"},
    +	{"DOUT2", NULL, "DOUT2 Route"},
    +	{"DOUT3", NULL, "DOUT3 Route"},
    +};
    +
    +#define AIC3262_DAPM_ROUTE_NUM (ARRAY_SIZE(aic3262_dapm_routes)/ \
    +					sizeof(struct snd_soc_dapm_route))
    +/* aic3262_firmware_load:   This function is called by the
    + *		request_firmware_nowait function as soon
    + *		as the firmware has been loaded from the file.
    + *		The firmware structure contains the data and$
    + *		the size of the firmware loaded.
    + * @fw: pointer to firmware file to be dowloaded
    + * @context: pointer variable to codec
    + *
    + * Returns 0 for success.
    + */
    +static void aic3262_firmware_load(const struct firmware *fw, void *context)
    +{
    +	struct snd_soc_component *codec = context;
    +	struct aic3262_priv *private_ds = snd_soc_component_get_drvdata(codec);
    +	int ret = 0;
    +
    +	aic3xxx_cfw_lock(private_ds->cfw_p, 1);
    +	if (private_ds->cur_fw != NULL)
    +		release_firmware(private_ds->cur_fw);
    +	private_ds->cur_fw = NULL;
    +
    +	if (fw != NULL) {
    +		dev_dbg(codec->dev, "Firmware binary load\n");
    +		private_ds->cur_fw = (void *)fw;
    +		ret = aic3xxx_cfw_reload(private_ds->cfw_p, (void *)fw->data,
    +			fw->size);
    +		if (ret < 0) { /* reload failed */
    +			dev_err(codec->dev, "Firmware binary load failed\n");
    +			release_firmware(private_ds->cur_fw);
    +			private_ds->cur_fw = NULL;
    +			fw = NULL;
    +		}
    +	} else {
    +		/* request_firmware failed*/
    +		/* could not locate file tlv320aic3262_fw_v1.bin
    +			under /vendor/firmare
    +		*/
    +		dev_err(codec->dev, "request_firmware failed\n");
    +		ret = -1;
    +	}
    +
    +	aic3xxx_cfw_lock(private_ds->cfw_p, 0);
    +	if (ret >= 0) {
    +		/*init function for transition */
    +		aic3xxx_cfw_transition(private_ds->cfw_p, "INIT");
    +		/* add firmware modes */
    +		aic3xxx_cfw_add_modes(codec, private_ds->cfw_p);
    +		/* add runtime controls */
    +		aic3xxx_cfw_add_controls(codec, private_ds->cfw_p);
    +		/* set the default firmware mode */
    +		aic3xxx_cfw_setmode_cfg(private_ds->cfw_p, 0, 0);
    +	}
    +
    +}
    +
    +/*=========================================================
    +
    + headset work and headphone/headset jack interrupt handlers
    +
    + ========================================================*/
    +
    +enum headset_accessory_state {
    +	BIT_NO_ACCESSORY = 0,
    +	BIT_HEADSET = (1 << 0),
    +	BIT_HEADPHONE = (1 << 1),
    +};
    +
    +/**
    + * aic3262_hs_jack_report: Report jack notication to upper layor
    + * @codec: pointer variable to codec having information related to codec
    + * @jack: Pointer variable to snd_soc_jack having information of codec
    + *		 and pin number$
    + * @report: Provides informaton of whether it is headphone or microphone
    + *
    +*/
    +static void aic3262_hs_jack_report(struct snd_soc_component *codec,
    +				   struct snd_soc_jack *jack, int report)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	int status, state = 0, switch_state = BIT_NO_ACCESSORY;
    +
    +	mutex_lock(&aic3262->mutex);
    +
    +	/* Sync status */
    +	status = snd_soc_component_read(codec, AIC3262_DAC_FLAG);
    +	/* We will check only stereo MIC and headphone */
    +	switch (status & AIC3262_JACK_TYPE_MASK) {
    +	case AIC3262_JACK_WITH_MIC:
    +		state |= SND_JACK_HEADSET;
    +		break;
    +	case AIC3262_JACK_WITHOUT_MIC:
    +		state |= SND_JACK_HEADPHONE;
    +	}
    +
    +	mutex_unlock(&aic3262->mutex);
    +
    +	snd_soc_jack_report(jack, state, report);
    +
    +	if ((state & SND_JACK_HEADSET) == SND_JACK_HEADSET)
    +		switch_state |= BIT_HEADSET;
    +	else if (state & SND_JACK_HEADPHONE)
    +		switch_state |= BIT_HEADPHONE;
    +
    +}
    +
    +/**
    + * aic3262_hs_jack_detect: Detect headphone jack during boot time
    + * @codec: pointer variable to codec having information related to codec
    + * @jack: Pointer variable to snd_soc_jack having information of codec
    + *	     and pin number$
    + * @report: Provides informaton of whether it is headphone or microphone
    + *
    +*/
    +void aic3262_hs_jack_detect(struct snd_soc_component *codec,
    +			    struct snd_soc_jack *jack, int report)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	struct aic3262_jack_data *hs_jack = &aic3262->hs_jack;
    +
    +	hs_jack->jack = jack;
    +	hs_jack->report = report;
    +	aic3262_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
    +}
    +EXPORT_SYMBOL_GPL(aic3262_hs_jack_detect);
    +/**
    + * aic3262_accessory_work: Finished bottom half work from headphone jack
    + *		insertion interupt
    + * @work: pionter variable to work_struct which is maintaining work queqe
    + *
    +*/
    +static void aic3262_accessory_work(struct work_struct *work)
    +{
    +	struct aic3262_priv *aic3262 = container_of(work,
    +						    struct aic3262_priv,
    +						    delayed_work.work);
    +	struct snd_soc_component *codec = aic3262->codec;
    +	struct aic3262_jack_data *hs_jack = &aic3262->hs_jack;
    +	aic3262_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
    +}
    +
    +/**
    + * aic3262_audio_handler: audio interrupt handler called
    + *		when interupt is generated
    + * @irq: provides interupt number which is assigned by aic3262_request_irq,
    + * @data having information of data passed by aic3262_request_irq last arg,
    + *
    + * Return IRQ_HANDLED(means interupt handeled successfully)
    +*/
    +static irqreturn_t aic3262_audio_handler(int irq, void *data)
    +{
    +	struct snd_soc_component *codec = data;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	queue_delayed_work(aic3262->workqueue, &aic3262->delayed_work,
    +			   msecs_to_jiffies(200));
    +	return IRQ_HANDLED;
    +}
    +
    +/**
    + * Methods for CFW Operations
    + *
    + * Due to incompatibilites between structures used by MFD and CFW
    + * we need to transform the register format before linking to
    + * CFW operations.
    + */
    +static inline unsigned int aic3262_ops_cfw2reg(unsigned int reg)
    +{
    +	union cfw_register *c = (union cfw_register *) ®
    +	union aic3xxx_reg_union mreg;
    +
    +	mreg.aic3xxx_register.offset = c->offset;
    +	mreg.aic3xxx_register.page = c->page;
    +	mreg.aic3xxx_register.book = c->book;
    +	mreg.aic3xxx_register.reserved = 0;
    +	return mreg.aic3xxx_register_int;
    +}
    +static int aic3262_ops_reg_read(struct snd_soc_component *codec, unsigned int reg)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_reg_read(aic3262->control_data, aic3262_ops_cfw2reg(reg));
    +}
    +
    +static int aic3262_ops_reg_write(struct snd_soc_component *codec, unsigned int reg,
    +			  unsigned char val)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_reg_write(aic3262->control_data,
    +					aic3262_ops_cfw2reg(reg), val);
    +}
    +
    +static int aic3262_ops_set_bits(struct snd_soc_component *codec, unsigned int reg,
    +				unsigned char mask, unsigned char val)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_set_bits(aic3262->control_data,
    +					aic3262_ops_cfw2reg(reg), mask, val);
    +
    +}
    +
    +static int aic3262_ops_bulk_read(struct snd_soc_component *codec, unsigned int reg,
    +				 int count, u8 *buf)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_bulk_read(aic3262->control_data,
    +					aic3262_ops_cfw2reg(reg), count, buf);
    +}
    +
    +static int aic3262_ops_bulk_write(struct snd_soc_component *codec, unsigned int reg,
    +			   int count, const u8 *buf)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_bulk_write(aic3262->control_data,
    +					aic3262_ops_cfw2reg(reg), count, buf);
    +}
    +
    +/**
    + * aic3262_ops_lock_lock: To Read the run state of the DAC and ADC
    + *			by reading the codec and returning the run state
    + * @pv: pointer argument to the codec
    + *
    + * Run state Bit format
    + *
    + * ------------------------------------------------------
    + * D31|..........| D7 | D6|  D5  |  D4  | D3 | D2 | D1  |   D0  |
    + * R               R    R   LADC   RADC    R    R   LDAC   RDAC
    + * ------------------------------------------------------
    + *
    + * R- Reserved
    + * LDAC- Left DAC
    + * RDAC- Right DAC
    + *
    + * Return value  : Integer
    + */
    +static int aic3262_ops_lock(struct snd_soc_component *codec)
    +{
    +	mutex_lock(&codec->io_mutex);
    +	/* Reading the run state of adc and dac */
    +	return aic3262_get_runstate(codec);
    +
    +}
    +
    +/**
    + * aic3262_ops_dlock_unlock: To unlock the mutex acqiured for reading
    + *			run state of the codec
    + * @pv: pointer argument to the codec
    + *
    + * Return Value: integer returning 0
    + */
    +static int aic3262_ops_unlock(struct snd_soc_component *codec)
    +{
    +	/*Releasing the lock of mutex */
    +	mutex_unlock(&codec->io_mutex);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_ops_dlock_stop:
    + * @pv: pointer Argument to the codec
    + * @mask: tells us the bit format of the codec running state
    + *
    + * Bit Format:
    + * ------------------------------------------------------
    + * D31|..........| D7 | D6| D5 | D4 | D3 | D2 | D1 | D0 |
    + * R               R    R   AL   AR    R    R   DL   DR
    + * ------------------------------------------------------
    + * R  - Reserved
    + * A  - minidsp_A
    + * D  - minidsp_D
    + *
    + * Return: return run state
    + */
    +static int aic3262_ops_stop(struct snd_soc_component *codec, int mask)
    +{
    +	int run_state = 0;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	run_state = aic3262_get_runstate(codec);
    +
    +	if (mask & AIC3XXX_COPS_MDSP_A)
    +		aic3xxx_set_bits(aic3262->control_data,
    +				 AIC3262_ADC_DATAPATH_SETUP, 0xC0, 0);
    +
    +	if (mask & AIC3XXX_COPS_MDSP_D)
    +		aic3xxx_set_bits(aic3262->control_data,
    +				 AIC3262_DAC_DATAPATH_SETUP, 0xC0, 0);
    +
    +	if ((mask & AIC3XXX_COPS_MDSP_A) &&
    +		!aic3xxx_wait_bits(aic3262->control_data,
    +				      AIC3262_ADC_FLAG, AIC3262_ADC_POWER_MASK,
    +				      0, AIC326X_TIME_DELAY,
    +				      AIC326X_DELAY_COUNTER))
    +		goto err;
    +
    +	if ((mask & AIC3XXX_COPS_MDSP_D) &&
    +		!aic3xxx_wait_bits(aic3262->control_data,
    +				      AIC3262_DAC_FLAG, AIC3262_DAC_POWER_MASK,
    +				      0, AIC326X_TIME_DELAY,
    +				      AIC326X_DELAY_COUNTER))
    +		goto err;
    +
    +	return run_state;
    +err:
    +	dev_err(codec->dev, "Unable to turn off ADCs or DACs at [%s:%d]",
    +				__FILE__, __LINE__);
    +	return -EINVAL;
    +}
    +
    +/**
    + * aic3262_ops_lock_restore: To unlock the mutex acqiured for reading
    + * @pv: pointer argument to the codec,run_state
    + * @run_state:  run state of the codec and to restore the states of the dsp
    + *
    + * Return Value	: integer returning 0
    + */
    +
    +static int aic3262_ops_restore(struct snd_soc_component *codec, int run_state)
    +{
    +	int sync_state;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	/* This is for read the sync mode register state  */
    +	sync_state = aic3xxx_reg_read(aic3262->control_data, AIC3262_DAC_PRB);
    +
    +	/*checking whether the sync mode has been set or
    +	   not and checking the current state */
    +	if (((run_state & 0x30) && (run_state & 0x03))&& (sync_state & 0x80))
    +		aic3262_restart_dsps_sync(codec, run_state);
    +	else
    +		aic3262_dsp_pwrup(codec, run_state);
    +
    +	return 0;
    +}
    +
    +/**
    + * aic3262_ops_adaptivebuffer_swap: To swap the coefficient buffers
    + *				 of minidsp according to mask
    + * @pv: pointer argument to the codec,
    + * @mask: tells us which dsp has to be chosen for swapping
    + *
    + * Return Value    : returning 0 on success
    + */
    +static int aic3262_ops_adaptivebuffer_swap(struct snd_soc_component *codec, int mask)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	const int sbuf[][2] = {
    +		{ AIC3XXX_ABUF_MDSP_A, AIC3262_ADC_ADAPTIVE_CRAM_REG },
    +		{ AIC3XXX_ABUF_MDSP_D1, AIC3262_DAC_ADAPTIVE_BANK1_REG },
    +		{ AIC3XXX_ABUF_MDSP_D2, AIC3262_DAC_ADAPTIVE_BANK2_REG },
    +	};
    +	int i;
    +
    +	for (i = 0; i < sizeof(sbuf)/sizeof(sbuf[0]); ++i) {
    +		if ((mask & sbuf[i][0])) {
    +			aic3xxx_set_bits(aic3262->control_data, sbuf[i][1],
    +					0x1, 0x1);
    +			if (!aic3xxx_wait_bits(aic3262->control_data,
    +						sbuf[i][1], 0x1, 0, 5, 1)) {
    +			dev_err(codec->dev, "miniDSP buffer swap failure");
    +			return -EINVAL;
    +			}
    +		}
    +	}
    +		return 0;
    +}
    +
    +/**
    + * get_runstate: To read the current state of the dac's and adc's
    + * @ps: pointer argument to the codec
    + *
    + * Return Value	: returning the runstate
    + */
    +static int aic3262_get_runstate(struct snd_soc_component *codec)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	unsigned int dac, adc;
    +	/* Read the run state */
    +	dac = aic3xxx_reg_read(aic3262->control_data, AIC3262_DAC_FLAG);
    +	adc = aic3xxx_reg_read(aic3262->control_data, AIC3262_ADC_FLAG);
    +
    +	return (((adc>>6)&1)<<5)  |
    +		(((adc>>2)&1)<<4) |
    +		(((dac>>7)&1)<<1) |
    +		(((dac>>3)&1)<<0);
    +}
    +
    +/**
    + * aic3262_dsp_pwrdwn_status: To read the status of dsp's
    + * @pv: pointer argument to the codec , cur_state of dac's and adc's
    + *
    + * Return Value	: integer returning 0
    + */
    +static int aic3262_dsp_pwrdwn_status(struct snd_soc_component *codec)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	aic3xxx_set_bits(aic3262->control_data,
    +			AIC3262_ADC_DATAPATH_SETUP, 0XC0, 0);
    +	aic3xxx_set_bits(aic3262->control_data,
    +			AIC3262_DAC_DATAPATH_SETUP, 0XC0, 0);
    +
    +	if (!aic3xxx_wait_bits(aic3262->control_data, AIC3262_ADC_FLAG,
    +			      AIC3262_ADC_POWER_MASK, 0, AIC326X_TIME_DELAY,
    +			      AIC326X_DELAY_COUNTER))
    +		goto err;
    +	if (!aic3xxx_wait_bits(aic3262->control_data, AIC3262_DAC_FLAG,
    +			      AIC3262_DAC_POWER_MASK, 0, AIC326X_TIME_DELAY,
    +			      AIC326X_DELAY_COUNTER))
    +		goto err;
    +
    +	return 0;
    +err:
    +	dev_err(codec->dev, "DAC/ADC Power down timedout at [%s:%d]",
    +				__FILE__, __LINE__);
    +	return -EINVAL;
    +}
    +static int aic3262_dsp_pwrup(struct snd_soc_component *codec, int state)
    +{
    +	int adc_reg_mask = 0;
    +	int adc_power_mask = 0;
    +	int dac_reg_mask = 0;
    +	int dac_power_mask = 0;
    +	int ret_wbits;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	if (state & AIC3XXX_COPS_MDSP_A_L) {
    +		adc_reg_mask |= 0x80;
    +		adc_power_mask |= AIC3262_LADC_POWER_MASK;
    +	}
    +	if (state & AIC3XXX_COPS_MDSP_A_R) {
    +		adc_reg_mask |= 0x40;
    +		adc_power_mask |= AIC3262_RADC_POWER_MASK;
    +	}
    +
    +	if (state & AIC3XXX_COPS_MDSP_A)
    +		aic3xxx_set_bits(aic3262->control_data,
    +					AIC3262_ADC_DATAPATH_SETUP, 0XC0,
    +					adc_reg_mask);
    +
    +	if (state & AIC3XXX_COPS_MDSP_D_L) {
    +		dac_reg_mask |= 0x80;
    +		dac_power_mask |= AIC3262_LDAC_POWER_STATUS_MASK;
    +	}
    +	if (state & AIC3XXX_COPS_MDSP_D_R) {
    +		dac_reg_mask |= 0x40;
    +		dac_power_mask |= AIC3262_RDAC_POWER_STATUS_MASK;
    +	}
    +
    +	if (state & AIC3XXX_COPS_MDSP_D)
    +		aic3xxx_set_bits(aic3262->control_data,
    +					AIC3262_DAC_DATAPATH_SETUP, 0XC0,
    +					dac_reg_mask);
    +
    +	if (state & AIC3XXX_COPS_MDSP_A) {
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +				AIC3262_ADC_FLAG, AIC3262_ADC_POWER_MASK,
    +				adc_power_mask, AIC326X_TIME_DELAY,
    +				AIC326X_DELAY_COUNTER);
    +		if (!ret_wbits)
    +			dev_err(codec->dev, "ADC Power down timedout\n");
    +	}
    +
    +	if (state & AIC3XXX_COPS_MDSP_D) {
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +				AIC3262_DAC_FLAG, AIC3262_DAC_POWER_MASK,
    +				dac_power_mask, AIC326X_TIME_DELAY,
    +				AIC326X_DELAY_COUNTER);
    +		if (!ret_wbits)
    +			dev_err(codec->dev, "ADC Power down timedout\n");
    +	}
    +
    +	return 0;
    +}
    +
    +static int aic3262_restart_dsps_sync(struct snd_soc_component *codec, int run_state)
    +{
    +
    +	aic3262_dsp_pwrdwn_status(codec);
    +	aic3262_dsp_pwrup(codec, run_state);
    +
    +	return 0;
    +}
    +
    +static const struct aic3xxx_codec_ops aic3262_cfw_codec_ops = {
    +	.reg_read  =	aic3262_ops_reg_read,
    +	.reg_write =	aic3262_ops_reg_write,
    +	.set_bits  =	aic3262_ops_set_bits,
    +	.bulk_read =	aic3262_ops_bulk_read,
    +	.bulk_write =	aic3262_ops_bulk_write,
    +	.lock      =	aic3262_ops_lock,
    +	.unlock    =	aic3262_ops_unlock,
    +	.stop      =	aic3262_ops_stop,
    +	.restore   =	aic3262_ops_restore,
    +	.bswap     =	aic3262_ops_adaptivebuffer_swap,
    +};
    +
    +
    +/**
    + * aic3262_codec_read: provide read api to read aic3262 registe space
    + * @codec: pointer variable to codec having codec information,
    + * @reg: register address,
    + *
    + * Return: Return value will be value read.
    + */
    +static unsigned int aic3262_codec_read(struct snd_soc_component *codec, unsigned int reg)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	u8 value;
    +
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	value = aic3xxx_reg_read(aic3262->control_data, reg);
    +	dev_dbg(codec->dev, "p %d , r 30 %x %x\n",
    +		aic_reg->aic3xxx_register.page,
    +		aic_reg->aic3xxx_register.offset, value);
    +	return value;
    +}
    +
    +/**
    + * aic3262_codec_write: provide write api to write at aic3262 registe space
    + * @codec: Pointer variable to codec having codec information,
    + * @reg: Register address,
    + * @value: Value to be written to address space
    + *
    + * Return: Total no of byte written to address space.
    + */
    +static int aic3262_codec_write(struct snd_soc_component *codec, unsigned int reg,
    +			unsigned int value)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +
    +	dev_dbg(codec->dev, "p %d, w 30 %x %x\n",
    +		aic_reg->aic3xxx_register.page,
    +		aic_reg->aic3xxx_register.offset, value);
    +	return aic3xxx_reg_write(aic3262->control_data, reg, value);
    +}
    +
    +/**
    + * aic3262_set_interface_fmt: Setting interface ASI1/2/3 data format
    + * @dai: ponter to dai Holds runtime data for a DAI,
    + * @fmt: asi format info,
    + * @channel: number of channel,
    + *
    + * Return: On success return 0.
    +*/
    +static int aic3262_set_interface_fmt(struct snd_soc_dai *dai, unsigned int fmt,
    +					unsigned int channel)
    +{
    +	int aif_interface_reg;
    +	int aif_bclk_offset_reg;
    +	struct snd_soc_component *codec = dai->component;
    +	u8 iface_val = 0;
    +	u8 dsp_a_val = 0;
    +
    +	switch (dai->id) {
    +	case 0:
    +		aif_interface_reg = AIC3262_ASI1_BUS_FMT;
    +		aif_bclk_offset_reg = AIC3262_ASI1_LCH_OFFSET;
    +		break;
    +	case 1:
    +		aif_interface_reg = AIC3262_ASI2_BUS_FMT;
    +		aif_bclk_offset_reg = AIC3262_ASI2_LCH_OFFSET;
    +		break;
    +	case 2:
    +		aif_interface_reg = AIC3262_ASI3_BUS_FMT;
    +		aif_bclk_offset_reg = AIC3262_ASI3_LCH_OFFSET;
    +		break;
    +	default:
    +		return -EINVAL;
    +
    +	}
    +	/* interface format */
    +	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    +	case SND_SOC_DAIFMT_I2S:
    +		iface_val = 0;
    +		break;
    +	case SND_SOC_DAIFMT_DSP_A:
    +		dsp_a_val = 0x1;	/* Intentionally falling through */
    +		fallthrough;
    +	case SND_SOC_DAIFMT_DSP_B:
    +		if (channel == 1)
    +			iface_val = 0x80;	/* Choose mono PCM */
    +		else if (channel <= 8)
    +			iface_val = 0x20;	/* choose multichannel PCM */
    +		else
    +			return -EINVAL;
    +		break;
    +	case SND_SOC_DAIFMT_RIGHT_J:
    +		iface_val = 0x40;
    +		break;
    +	case SND_SOC_DAIFMT_LEFT_J:
    +		iface_val = 0x60;
    +		break;
    +	default:
    +		dev_err(codec->dev, "Invalid DAI interface format\n");
    +		return -EINVAL;
    +	}
    +	snd_soc_component_update_bits(codec, aif_interface_reg,
    +					AIC3262_ASI_INTERFACE_MASK, iface_val);
    +	snd_soc_component_update_bits(codec, aif_bclk_offset_reg,
    +					AIC3262_BCLK_OFFSET_MASK, dsp_a_val);
    +	return 0;
    +
    +}
    +
    +/**
    + * aic3262_hw_params: This function is to set the hardware parameters
    + *		for AIC3262.
    + *		The functions set the sample rate and audio serial data word
    + *		length.
    + * @substream: pointer variable to sn_pcm_substream,
    + * @params: pointer to snd_pcm_hw_params structure,
    + * @dai: ponter to dai Holds runtime data for a DAI,
    + *
    + * Return: Return 0 on success.
    + */
    +int aic3262_hw_params(struct snd_pcm_substream *substream,
    +			struct snd_pcm_hw_params *params,
    +			struct snd_soc_dai *dai)
    +{
    +	struct snd_soc_component *codec = dai->component;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	int asi_reg, ret = 0;
    +	u8 data = 0, value = 0, val = 0, wclk_div = 0, bclk_div = 0;
    +	unsigned int channels = params_channels(params);
    +
    +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    +		aic3262->stream_status = 1;
    +	else
    +		aic3262->stream_status = 0;
    +
    +	switch (dai->id) {
    +	case 0:
    +		asi_reg = AIC3262_ASI1_BUS_FMT;
    +		break;
    +	case 1:
    +		asi_reg = AIC3262_ASI2_BUS_FMT;
    +		break;
    +	case 2:
    +		asi_reg = AIC3262_ASI3_BUS_FMT;
    +		break;
    +	default:
    +		return -EINVAL;
    +	}
    +
    +	switch (params_format(params)) {
    +	case SNDRV_PCM_FORMAT_S16_LE:
    +		data = data | 0x00;
    +		break;
    +	case SNDRV_PCM_FORMAT_S20_3LE:
    +		data |= (0x08);
    +		break;
    +	case SNDRV_PCM_FORMAT_S24_LE:
    +		data |= (0x10);
    +		break;
    +	case SNDRV_PCM_FORMAT_S32_LE:
    +		data |= (0x18);
    +		break;
    +	}
    +
    +	/* Configure TDM for multi chennels */
    +	switch (channels) {
    +	case 4:
    +		value = value | 0x40;
    +		bclk_div = 0x03;
    +		wclk_div = 0x40;
    +		break;
    +	case 6:
    +		bclk_div = 0x02;
    +		wclk_div = 0x60;
    +		value = value | 0x80;
    +		break;
    +	case 8:
    +		bclk_div = 0x01;
    +		wclk_div = 0x00;
    +		value = value | 0xC0;
    +		break;
    +	default:
    +		bclk_div = 0x04;
    +		wclk_div = 0x20;
    +	}
    +
    +	snd_soc_component_update_bits(codec, AIC3262_ASI1_CHNL_SETUP,
    +				AIC3262_ASI1_CHNL_MASK, value);
    +
    +	snd_soc_component_update_bits(codec, AIC3262_ASI1_BCLK_N,
    +				AIC3262_ASI1_BCLK_N_MASK, bclk_div);
    +
    +	snd_soc_component_update_bits(codec, AIC3262_ASI1_WCLK_N,
    +				AIC3262_ASI1_WCLK_N_MASK, wclk_div);
    +
    +
    +	val = snd_soc_component_read(codec, AIC3262_ASI1_BUS_FMT);
    +	val = snd_soc_component_read(codec, AIC3262_ASI1_CHNL_SETUP);
    +
    +	/* configure the respective Registers for the above configuration */
    +	snd_soc_component_update_bits(codec, asi_reg,
    +			    AIC3262_ASI_DATA_WORD_LENGTH_MASK, data);
    +	ret = aic3262_set_interface_fmt(dai, aic3262->asi_fmt[dai->id],
    +					 channels);
    +	if (ret < 0) {
    +		dev_err(codec->dev, "failed to set hardware params for AIC3262\n");
    +		return ret;
    +	}
    +
    +	return 0;
    +}
    +
    +/**
    + * aic3262_mute: This function is to mute or unmute the left and right DAC
    + * @dai: ponter to dai Holds runtime data for a DAI,
    + * @mute: integer value one if we using mute else unmute,
    + *
    + * Return: return 0 on success.
    + */
    +static int aic3262_mute(struct snd_soc_dai *dai, int mute, int stream)
    +{
    +	struct snd_soc_component *codec = dai->component;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	dev_dbg(codec->dev, "codec : %s : started\n", __func__);
    +	if (dai->id > 2)
    +		return -EINVAL;
    +	if (mute) {
    +		aic3262->mute_asi &= ~((0x1) << dai->id);
    +		if (aic3262->mute_asi == 0)
    +			/* Mute only when all asi's are muted */
    +			snd_soc_component_update_bits(codec,
    +						   AIC3262_DAC_MVOL_CONF,
    +						   AIC3262_DAC_LR_MUTE_MASK,
    +						   AIC3262_DAC_LR_MUTE);
    +
    +	} else {	/* Unmute */
    +		if (aic3262->mute_asi == 0)
    +			/* Unmute for the first asi that need to unmute.
    +			   rest unmute will pass */
    +			snd_soc_component_update_bits(codec,
    +						   AIC3262_DAC_MVOL_CONF,
    +						   AIC3262_DAC_LR_MUTE_MASK,
    +						   0x0);
    +		aic3262->mute_asi |= ((0x1) << dai->id);
    +	}
    +	dev_dbg(codec->dev, "codec : %s : ended\n", __func__);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_set_dai_fmt: This function is to set the DAI format
    + * @codec_dai: ponter to dai Holds runtime data for a DAI,
    + * @fmt: asi format info,
    + *
    + * return: return 0 on success.
    + */
    +static int aic3262_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
    +{
    +	struct aic3262_priv *aic3262;
    +	struct snd_soc_component *codec;
    +	u8 iface_val, master;
    +	int aif_bclk_wclk_reg;
    +
    +	codec = codec_dai->component;
    +	aic3262 = snd_soc_component_get_drvdata(codec);
    +	iface_val = 0x00;
    +	master = 0x0;
    +
    +	switch (codec_dai->id) {
    +	case 0:
    +		aif_bclk_wclk_reg = AIC3262_ASI1_BWCLK_CNTL_REG;
    +		break;
    +	case 1:
    +		aif_bclk_wclk_reg = AIC3262_ASI2_BWCLK_CNTL_REG;
    +		break;
    +	case 2:
    +		aif_bclk_wclk_reg = AIC3262_ASI3_BWCLK_CNTL_REG;
    +		break;
    +	default:
    +		return -EINVAL;
    +
    +	}
    +	aic3262->asi_fmt[codec_dai->id] = fmt;
    +	/* set master/slave audio interface */
    +	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
    +	case SND_SOC_DAIFMT_CBP_CFP:
    +		aic3262->master = 1;
    +		master |= (AIC3262_WCLK_OUT_MASK | AIC3262_BCLK_OUT_MASK);
    +		break;
    +	case SND_SOC_DAIFMT_CBC_CFC:
    +		aic3262->master = 0;
    +		break;
    +	case SND_SOC_DAIFMT_CBC_CFP:	/* new case..for debug purpose */
    +		master |= (AIC3262_WCLK_OUT_MASK);
    +		aic3262->master = 0;
    +		break;
    +	case SND_SOC_DAIFMT_CBP_CFC:
    +		master |= (AIC3262_BCLK_OUT_MASK);
    +		aic3262->master = 0;
    +		break;
    +
    +	default:
    +		dev_err(codec->dev, "Invalid DAI master/slave" " interface\n");
    +
    +		return -EINVAL;
    +	}
    +	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    +	case SND_SOC_DAIFMT_DSP_A:
    +	case SND_SOC_DAIFMT_DSP_B:
    +		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    +		case SND_SOC_DAIFMT_NB_NF:
    +			break;
    +		case SND_SOC_DAIFMT_IB_NF:
    +			master |= AIC3262_BCLK_INV_MASK;
    +			break;
    +		default:
    +			return -EINVAL;
    +		}
    +		break;
    +	case SND_SOC_DAIFMT_I2S:
    +	case SND_SOC_DAIFMT_RIGHT_J:
    +	case SND_SOC_DAIFMT_LEFT_J:
    +		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    +		case SND_SOC_DAIFMT_NB_NF:
    +			break;
    +		case SND_SOC_DAIFMT_IB_NF:
    +			master |= AIC3262_BCLK_INV_MASK;
    +			break;
    +		default:
    +			return -EINVAL;
    +		}
    +		break;
    +	default:
    +		return -EINVAL;
    +	}
    +	snd_soc_component_update_bits(codec, aif_bclk_wclk_reg,
    +			    AIC3262_WCLK_BCLK_MASTER_MASK, master);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_dai_set_pll: This function is to Set pll for aic3262 codec dai
    + * @dai: ponter to dai Holds runtime data for a DAI,$
    + * @pll_id: integer pll_id
    + * @source: DAI specific source for the PLL
    + * @fin: PLL Input clock frequency in Hz,
    + * @fout: Frequency out,
    + *
    + * Return: return 0 on success
    +*/
    +static int aic3262_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
    +				unsigned int Fin, unsigned int Fout)
    +{
    +	struct snd_soc_component *codec = dai->component;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	dev_dbg(codec->dev, "In aic3262: dai_set_pll\n");
    +	dev_dbg(codec->dev, "%d, %s, dai->id = %d\n", __LINE__,
    +		__func__, dai->id);
    +	/* select the PLL_CLKIN */
    +	snd_soc_component_update_bits(codec, AIC3262_PLL_CLKIN_REG,
    +			    AIC3262_PLL_CLKIN_MASK, source <<
    +			    AIC3262_PLL_CLKIN_SHIFT);
    +	/* TODO: How to select low/high clock range? */
    +
    +	aic3xxx_cfw_set_pll(aic3262->cfw_p, dai->id);
    +
    +	return 0;
    +}
    +
    +/**
    + *
    + * aic3262_set_bias_level: This function is to get triggered
    + *			 when dapm events occurs.
    + * @codec: pointer variable to codec having informaton related to codec,
    + * @level: Bias level-> ON, PREPARE, STANDBY, OFF.
    + *
    + * Return: Return 0 on success.
    + */
    +static int aic3262_set_bias_level(struct snd_soc_component *codec,
    +				  enum snd_soc_bias_level level)
    +{
    +
    +	switch (level) {
    +		/* full On */
    +	case SND_SOC_BIAS_ON:
    +
    +		dev_dbg(codec->dev, "set_bias_on\n");
    +		break;
    +
    +		/* partial On */
    +	case SND_SOC_BIAS_PREPARE:
    +		dev_dbg(codec->dev, "set_bias_prepare\n");
    +		break;
    +
    +		/* Off, with power */
    +	case SND_SOC_BIAS_STANDBY:
    +		/*
    +		 * all power is driven by DAPM system,
    +		 * so output power is safe if bypass was set
    +		 */
    +		dev_dbg(codec->dev, "set_bias_stby\n");
    +		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
    +			pm_runtime_get_sync(codec->dev);
    +			snd_soc_component_update_bits(codec, AIC3262_POWER_CONF,
    +					    (AIC3262_AVDD_TO_DVDD_MASK |
    +					     AIC3262_EXT_ANALOG_SUPPLY_MASK),
    +					    0x0);
    +			snd_soc_component_update_bits(codec, AIC3262_REF_PWR_DLY,
    +					    AIC3262_CHIP_REF_PWR_ON_MASK,
    +					    AIC3262_CHIP_REF_PWR_ON);
    +			mdelay(40);
    +
    +			snd_soc_component_update_bits(codec, AIC3262_CHARGE_PUMP_CNTL,
    +				AIC3262_DYNAMIC_OFFSET_CALIB_MASK,
    +				AIC3262_DYNAMIC_OFFSET_CALIB);
    +		}
    +		break;
    +
    +		/* Off, without power */
    +	case SND_SOC_BIAS_OFF:
    +		dev_dbg(codec->dev, "set_bias_off\n");
    +		/* force all power off */
    +		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
    +			snd_soc_component_update_bits(codec, AIC3262_REF_PWR_DLY,
    +					    AIC3262_CHIP_REF_PWR_ON_MASK, 0x0);
    +			snd_soc_component_update_bits(codec, AIC3262_POWER_CONF,
    +					    (AIC3262_AVDD_TO_DVDD_MASK |
    +					     AIC3262_EXT_ANALOG_SUPPLY_MASK),
    +					    (AIC3262_AVDD_TO_DVDD |
    +					     AIC3262_EXT_ANALOG_SUPPLY_OFF));
    +			pm_runtime_put(codec->dev);
    +		}
    +		break;
    +	}
    +
    +	codec->dapm.bias_level = level;
    +	return 0;
    +}
    +
    +/**
    + *
    + * aic3262_suspend; This function is to suspend the AIC3262 driver.
    + * @codec: pointer variable to codec having informaton related to codec,
    + *
    + * Return: Return 0 on success.
    + */
    +static int aic3262_suspend(struct snd_soc_component *codec)
    +{
    +	aic3262_set_bias_level(codec, SND_SOC_BIAS_OFF);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_resume: This function is to resume the AIC3262 driver
    + *		 from off state to standby
    + * @codec: pointer variable to codec having informaton related to codec,
    + *
    + * Return: Return 0 on success.
    + */
    +static int aic3262_resume(struct snd_soc_component *codec)
    +{
    +	aic3262_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
    +
    +	return 0;
    +}
    +
    +/**
    + * aic3262_probe: This is first driver function called by the SoC core driver.
    + * @codec: pointer variable to codec having informaton related to codec,
    + *
    + * Return: Return 0 on success.
    + */
    +static int aic3262_codec_probe(struct snd_soc_component *codec)
    +{
    +	int ret = 0;
    +	struct aic3xxx *control;
    +	struct aic3262_priv *aic3262;
    +
    +	if (codec == NULL)
    +		dev_err(codec->dev, "codec pointer is NULL.\n");
    +
    +	control = dev_get_drvdata(codec->dev->parent);
    +	aic3262 = kzalloc(sizeof(struct aic3262_priv), GFP_KERNEL);
    +	if (aic3262 == NULL)
    +		return -ENOMEM;
    +
    +	aic3262->control_data = control;
    +	snd_soc_component_set_drvdata(codec, aic3262);
    +	aic3262->pdata = dev_get_platdata(codec->dev->parent);
    +	aic3262->codec = codec;
    +	aic3262->cur_fw = NULL;
    +	aic3262->cfw_p = &(aic3262->cfw_ps);
    +	aic3xxx_cfw_init(aic3262->cfw_p, &aic3262_cfw_codec_ops,
    +							aic3262->codec);
    +	aic3262->workqueue = create_singlethread_workqueue("aic3262-codec");
    +	if (!aic3262->workqueue) {
    +		ret = -ENOMEM;
    +		goto work_err;
    +	}
    +	INIT_DELAYED_WORK(&aic3262->delayed_work, aic3262_accessory_work);
    +	mutex_init(&aic3262->mutex);
    +	mutex_init(&codec->io_mutex);
    +	mutex_init(&aic3262->cfw_mutex);
    +	pm_runtime_enable(codec->dev);
    +	pm_runtime_resume(codec->dev);
    +		aic3262->dsp_runstate = 0;
    +
    +	if (control->irq) {
    +		ret = aic3xxx_request_irq(aic3262->control_data,
    +					  AIC3262_IRQ_HEADSET_DETECT,
    +					  aic3262_audio_handler,
    +					  IRQF_NO_SUSPEND,
    +					  "aic3262_irq_headset", codec);
    +
    +		if (ret) {
    +			dev_err(codec->dev,
    +				"HEADSET detect irq request failed:%d\n", ret);
    +			goto irq_err;
    +		} else {
    +
    +			/*  Dynamic Headset Detection Enabled */
    +
    +			snd_soc_component_update_bits(codec, AIC3262_HP_DETECT,
    +					AIC3262_HEADSET_IN_MASK,
    +					AIC3262_HEADSET_IN_MASK);
    +		}
    +	}
    +	/* Keep the reference voltage ON while in
    +	   STANDBY mode for fast power up */
    +
    +	snd_soc_component_update_bits(codec, AIC3262_REF_PWR_DLY,
    +			    AIC3262_CHIP_REF_PWR_ON_MASK,
    +			    AIC3262_CHIP_REF_PWR_ON);
    +	mdelay(40);
    +
    +	snd_soc_component_update_bits(codec, AIC3262_CHARGE_PUMP_CNTL,
    +				AIC3262_DYNAMIC_OFFSET_CALIB_MASK,
    +				AIC3262_DYNAMIC_OFFSET_CALIB);
    +
    +	aic3262_set_bias_level(codec, SND_SOC_BIAS_OFF);
    +
    +	aic3262->mute_asi = 0;
    +
    +	ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
    +				"tlv320aic3262_fw_v1.bin", codec->dev,
    +				GFP_KERNEL, codec, aic3262_firmware_load);
    +	if (ret < 0) {
    +		dev_err(codec->dev, "Firmware request failed\n");
    +		goto firm_err;
    +	}
    +
    +	return 0;
    +firm_err:
    +	aic3xxx_free_irq(control,
    +			 AIC3262_IRQ_HEADSET_DETECT, codec);
    +irq_err:
    +	destroy_workqueue(aic3262->workqueue);
    +work_err:
    +	kfree(aic3262);
    +	return 0;
    +}
    +
    +/*
    + * aic3262_remove: Cleans up and Remove aic3262 soc device
    + * @codec: pointer variable to codec having informaton related to codec,
    + *
    + * Return: Return 0 on success.
    + */
    +static void aic3262_codec_remove(struct snd_soc_component *codec)
    +{
    +	/* power down chip */
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	struct aic3xxx *control = aic3262->control_data;
    +
    +	aic3262_set_bias_level(codec, SND_SOC_BIAS_OFF);
    +
    +	/* free_irq if any */
    +	switch (control->type) {
    +	case TLV320AIC3262:
    +		if (control->irq)
    +			aic3xxx_free_irq(control,
    +					 AIC3262_IRQ_HEADSET_DETECT, codec);
    +		break;
    +	default:
    +		dev_info(codec->dev, "Coded is not TLV320AIC3262\n");
    +	}
    +	/* release firmware if any */
    +	if (aic3262->cur_fw != NULL)
    +		release_firmware(aic3262->cur_fw);
    +	/* destroy workqueue for jac dev */
    +	destroy_workqueue(aic3262->workqueue);
    +
    +	kfree(aic3262);
    +}
    +
    +static struct snd_soc_component_driver soc_codec_driver_aic326x = {
    +	.probe = aic3262_codec_probe,
    +	.remove = aic3262_codec_remove,
    +	.suspend = aic3262_suspend,
    +	.resume = aic3262_resume,
    +	.read = aic3262_codec_read,
    +	.write = aic3262_codec_write,
    +	.controls = aic3262_snd_controls,
    +	.num_controls = ARRAY_SIZE(aic3262_snd_controls),
    +	.dapm_widgets = aic3262_dapm_widgets,
    +	.num_dapm_widgets = ARRAY_SIZE(aic3262_dapm_widgets),
    +	.dapm_routes = aic3262_dapm_routes,
    +	.num_dapm_routes = ARRAY_SIZE(aic3262_dapm_routes),
    +	.set_bias_level = aic3262_set_bias_level,
    +	//.reg_cache_size = 0,
    +	//.reg_word_size = sizeof(u8),
    +	//.reg_cache_default = NULL,
    +};
    +
    +static int aic326x_probe(struct platform_device *pdev)
    +{
    +	return snd_soc_register_component(&pdev->dev, &soc_codec_driver_aic326x,
    +					  aic326x_dai_driver,
    +					  ARRAY_SIZE(aic326x_dai_driver));
    +
    +}
    +
    +static void aic326x_remove(struct platform_device *pdev)
    +{
    +	snd_soc_unregister_component(&pdev->dev);
    +}
    +
    +static const struct of_device_id aic3262_of_match[] = {
    +		{ .compatible = "ti,aic3262", },
    +		{ .compatible = "ti,aic3268", },
    +		{ },
    +};
    +MODULE_DEVICE_TABLE(of, aic3262_of_match);
    +
    +static const struct platform_device_id aic3262_i2c_id[] = {
    +		{ "tlv320aic3262-codec", 0 },
    +		{ "tlv320aic3268-codec", 1 },
    +		{ }
    +};
    +MODULE_DEVICE_TABLE(i2c, aic3262_i2c_id);
    +
    +static struct platform_driver aic326x_codec_driver = {
    +	.driver = {
    +		.name = "tlv320aic3262-codec",
    +		.owner = THIS_MODULE,
    +		.of_match_table = aic3262_of_match,
    +	},
    +	.probe = aic326x_probe,
    +	.remove = aic326x_remove,
    +	.id_table = aic3262_i2c_id,
    +};
    +
    +module_platform_driver(aic326x_codec_driver);
    +
    +MODULE_ALIAS("platform:tlv320aic326x-codec");
    +MODULE_DESCRIPTION("ASoC TLV320AIC326X codec driver");
    +MODULE_AUTHOR("Y Preetam Sashank Reddy ");
    +MODULE_AUTHOR("Barani Prashanth ");
    +MODULE_AUTHOR("Mukund Navada K <navada@ti.com>");
    +MODULE_AUTHOR("Naren Vasanad <naren.vasanad@ti.com>");
    +MODULE_LICENSE("GPL");
    diff --git a/sound/soc/codecs/tlv320aic326x.h b/sound/soc/codecs/tlv320aic326x.h
    new file mode 100644
    index 000000000..b20bb447e
    --- /dev/null
    +++ b/sound/soc/codecs/tlv320aic326x.h
    @@ -0,0 +1,134 @@
    +/*
    + * linux/sound/soc/codecs/tlv320aic326x.h
    + *
    + * Copyright (C) 2011 TI Solutions Pvt Ltd.
    + *
    + * Based on sound/soc/codecs/tlv320aic3262.c
    + *
    + * This package is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2 as
    + * published by the Free Software Foundation.
    + *
    + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
    + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    + *
    + * The TLV320AIC3262 is a flexible, low-power, low-voltage stereo audio
    + * codec with digital microphone inputs and programmable outputs.
    + *
    + * History:
    + *
    + * Rev 0.1   ASoC driver support    TI         20-01-2011
    + *		The AIC325x ASoC driver is ported for the codec AIC3262.
    + * Rev 0.2   ASoC driver support    TI         21-03-2011
    + *		The AIC326x ASoC driver is updated for linux 2.6.32 Kernel.
    + * Rev 0.3   ASoC driver support    TI         20-04-2011
    + *		The AIC326x ASoC driver is ported to 2.6.35 omap4 kernel
    + */
    +
    +#ifndef _TLV320AIC3262_H
    +#define _TLV320AIC3262_H
    +#include "aic3xxx/aic3xxx_cfw.h"
    +#include "aic3xxx/aic3xxx_cfw_ops.h"
    +
    +#define AUDIO_NAME "aic3262"
    +#define AIC3262_VERSION "1.1"
    +/* Macro to enable the inclusion of tiload kernel driver */
    +#define AIC3262_TiLoad
    +#undef AIC3262_SYNC_MODE
    +#define AIC3262_ASI1_MASTER
    +#undef AIC3262_ASI2_MASTER
    +#undef AIC3262_ASI3_MASTER
    +/* Macro for McBsp master / slave configuration */
    +#define AIC3262_MCBSP_SLAVE	/*3262 master */
    +
    +/* Enable this macro allow for different ASI formats */
    +#undef ASI_MULTI_FMT
    +
    +/* Enable or disable controls to have Input routing*/
    +#undef FULL_IN_CNTL
    +/* AIC3262 supported sample rate are 8k to 192k */
    +#define AIC3262_RATES	SNDRV_PCM_RATE_8000_192000
    +
    +/* AIC3262 supports the word formats 16bits, 20bits, 24bits and 32 bits */
    +#define AIC3262_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
    +			 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
    +
    +#define AIC3262_FREQ_12000000 12000000
    +#define AIC3262_FREQ_19200000 19200000
    +#define AIC3262_FREQ_24000000 24000000
    +#define AIC3262_FREQ_38400000 38400000
    +/* Audio data word length = 16-bits (default setting) */
    +#define AIC3262_WORD_LEN_16BITS		0x00
    +#define AIC3262_WORD_LEN_20BITS		0x01
    +#define AIC3262_WORD_LEN_24BITS		0x02
    +#define AIC3262_WORD_LEN_32BITS		0x03
    +
    +/* sink: name of target widget */
    +#define AIC3262_WIDGET_NAME			0
    +/* control: mixer control name */
    +#define AIC3262_CONTROL_NAME			1
    +/* source: name of source name */
    +#define AIC3262_SOURCE_NAME			2
    +
    +/* D15..D8 aic3262 register offset */
    +#define AIC3262_REG_OFFSET_INDEX		0
    +/* D7...D0 register data */
    +#define AIC3262_REG_DATA_INDEX			1
    +
    +/* Serial data bus uses I2S mode (Default mode) */
    +#define AIC3262_I2S_MODE				0x00
    +#define AIC3262_DSP_MODE				0x01
    +#define AIC3262_RIGHT_JUSTIFIED_MODE			0x02
    +#define AIC3262_LEFT_JUSTIFIED_MODE			0x03
    +
    +/* 8 bit mask value */
    +#define AIC3262_8BITS_MASK				0xFF
    +
    +/* shift value for CLK_REG_3 register */
    +#define CLK_REG_3_SHIFT					6
    +/* shift value for DAC_OSR_MSB register */
    +#define DAC_OSR_MSB_SHIFT				4
    +
    +/* number of codec specific register for configuration */
    +#define NO_FEATURE_REGS				2
    +
    +/* AIC3262 register space */
    +/* Updated from 256 to support Page 3 registers */
    +#define	AIC3262_CACHEREGNUM				1024
    +
    +#define AIC326X_TIME_DELAY					5
    +#define AIC326X_DELAY_COUNTER					100
    +
    +struct aic3262_jack_data {
    +	struct snd_soc_jack *jack;
    +	int report;
    +};
    +
    +struct aic3262_priv {
    +	u32 sysclk;
    +	s32 master;
    +	u8 stream_status;
    +	struct aic3262_jack_data hs_jack;
    +	struct workqueue_struct *workqueue;
    +	struct delayed_work delayed_work;
    +	struct input_dev *idev;
    +	struct snd_soc_component *codec;
    +	struct mutex mutex;
    +	struct mutex cfw_mutex;
    +	struct cfw_state cfw_ps;
    +	struct cfw_state *cfw_p;
    +	struct aic3262_pdata *pdata;
    +	int mute_asi;	/* Bit 0 -> ASI1, Bit 1-> ASI2, Bit 2 -> ASI3 */
    +	int asi_fmt[2];
    +	int dsp_runstate;
    +	struct firmware *cur_fw;
    +	struct aic3xxx *control_data;
    +	int isdefault_fw;
    +};
    +
    +extern struct snd_soc_dai tlv320aic3262_dai;
    +void aic3262_hs_jack_detect(struct snd_soc_component *codec,
    +			    struct snd_soc_jack *jack, int report);
    +
    +#endif /* _TLV320AIC3262_H */
    -- 
    2.39.5
    
    

    Regards

    Niranjan

  • Hi  ,

    Have you applied the patch on the files tlv320aic326x.ctlv320aic326x.h  downloaded from this link (as these files are not present by default in the 6.1 kernel)?
    [FAQ] Linux Drivers: Device drivers for AIC31xx/DAC31xx/AIC325x/AIC320x/AIC326x/AIC321x


    Shall i save this to a  xvz.patch file and then apply the patch using git am command in kernel directory?

    Please tell proper procedure to apply this patch.


    Thanks!

    -Vishal

  • This is independent patch. I applied on top of fresh ti-processor-sdk-linux-am57xx-evm-09_03_06_05-Linux-x86-Install.bin installation as below. 

    Steps:

    • Copy paste the contents to file and save as test.patch
    • You can use "git am" to apply the patch

    ~/sdk/install/board-support/ti-linux-kernel-6.1.119+gitAUTOINC+e4e8b16e66-ti$ git am test.patch
    Applying: add tlv320aic3262 to kernel version 6.1
    .git/rebase-apply/patch:1198: trailing whitespace.
    #define AIC3262_JACK_TYPE_MASK (0b00110000)
    .git/rebase-apply/patch:1434: new blank line at EOF.
    +
    .git/rebase-apply/patch:3451: new blank line at EOF.
    +
    warning: 3 lines add whitespace errors.

    • Verify the patch is applied
       
      ~/sdk/install/board-support/ti-linux-kernel-6.1.119+gitAUTOINC+e4e8b16e66-ti$ git log --oneline -n12
      ac96d59fe (HEAD -> ti-linux-6.1.y) add tlv320aic3262 to kernel version 6.1
      e4e8b16e6 (grafted, tag: cicd.kirkstone.202412111800) arm: dts: am57xx: Extend IPU Late Attach support to all AM57xx platforms

    Regards,

    Niranjan

  • Hi  ,

    Thanks for the procedure, the patch got successfully applied. 

    After applying patch, I enabled the driver in .config using make menuconfig

    Here is the git diff output after enabling it. 

    diff --git a/.config b/.config
    index cf0d02cd3..6c8e65f86 100644
    --- a/.config
    +++ b/.config
    @@ -3453,6 +3453,9 @@ CONFIG_MFD_CPCAP=y
    # CONFIG_MFD_VIPERBOARD is not set
    # CONFIG_MFD_NTXEC is not set
    # CONFIG_MFD_RETU is not set
    +CONFIG_AIC3XXX_I2C_REGMAP=y
    +# CONFIG_AIC3XXX_SPI_REGMAP is not set
    +# CONFIG_AIC3XXX_CORE is not set
    # CONFIG_MFD_PCF50633 is not set
    # CONFIG_UCB1400_CORE is not set
    # CONFIG_MFD_PM8XXX is not set
    @@ -4971,6 +4974,7 @@ CONFIG_SND_SOC_TLV320AIC3X=m
    CONFIG_SND_SOC_TLV320AIC3X_I2C=m
    # CONFIG_SND_SOC_TLV320AIC3X_SPI is not set
    # CONFIG_SND_SOC_TLV320ADCX140 is not set
    +CONFIG_SND_SOC_AIC3262=m
    CONFIG_SND_SOC_TS3A227E=m
    # CONFIG_SND_SOC_TSCS42XX is not set
    # CONFIG_SND_SOC_TSCS454 is not set

    Now when I compile the kernel I am getting the following error:-

    make
      CALL    scripts/checksyscalls.sh
      CC [M]  sound/soc/codecs/tlv320aic326x.o
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_cfw2reg':
    sound/soc/codecs/tlv320aic326x.c:1652:56: error: stray '\302' in program
     1652 |         union cfw_register *c = (union cfw_register *) <U+00AE>
          |                                                        ^~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:1653:9: error: expected expression before 'union'
     1653 |         union aic3xxx_reg_union mreg;
          |         ^~~~~
    sound/soc/codecs/tlv320aic326x.c:1655:9: error: 'mreg' undeclared (first use in this function); did you mean 'reg'?
     1655 |         mreg.aic3xxx_register.offset = c->offset;
          |         ^~~~
          |         reg
    sound/soc/codecs/tlv320aic326x.c:1655:9: note: each undeclared identifier is reported only once for each function it appears in
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_codec_read':
    sound/soc/codecs/tlv320aic326x.c:1993:72: error: stray '\302' in program
     1993 |         union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) <U+00AE>
          |                                                                        ^~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:1993:44: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     1993 |         union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
          |                                            ^
    sound/soc/codecs/tlv320aic326x.c:1994:15: error: lvalue required as left operand of assignment
     1994 |         value = aic3xxx_reg_read(aic3262->control_data, reg);
          |               ^
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_codec_write':
    sound/soc/codecs/tlv320aic326x.c:2013:72: error: stray '\302' in program
     2013 |         union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) <U+00AE>
          |                                                                        ^~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2013:44: error: invalid use of void expression
     2013 |         union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
          |                                            ^
    sound/soc/codecs/tlv320aic326x.c: In function 'aic3262_ops_cfw2reg':
    sound/soc/codecs/tlv320aic326x.c:1660:1: error: control reaches end of non-void function [-Werror=return-type]
     1660 | }
          | ^
    cc1: some warnings being treated as errors
    make[4]: *** [scripts/Makefile.build:250: sound/soc/codecs/tlv320aic326x.o] Error 1
    make[3]: *** [scripts/Makefile.build:505: sound/soc/codecs] Error 2
    make[2]: *** [scripts/Makefile.build:505: sound/soc] Error 2
    make[1]: *** [scripts/Makefile.build:505: sound] Error 2
    make: *** [Makefile:2009: .] Error 2
    

    There are certain strange characters in code -> ® in you patch which is definitely not C code ( as shown below):-

    union cfw_register *c = (union cfw_register *) ®

    Please give final working code rectifying the errors in code. Thanks!

    -Vishal

  • For some reason the below string is becoming the special character when paste here. 

    Could you please replace it with manually in those places and check again as I am not able to attach files. thanks 

    ®
      &reg;

  • Hi  ,

    I had just done the same change already before viewing your reply and my driver got compiled, but thanks anyways!!
    Now I will test the driver and revert !

    Thanks

    -Vishal

  • Hi  ,

    Upon booting the kernel I saw that the driver got loaded as shown in the prints below:-

    lsmod | grep snd 
    snd_soc_davinci_mcasp    28672  0
    snd_soc_tlv320aic3262    73728  0
    snd_soc_simple_card    20480  0
    snd_soc_ti_udma        16384  1 snd_soc_davinci_mcasp
    snd_soc_ti_edma        16384  1 snd_soc_davinci_mcasp
    snd_soc_simple_card_utils    20480  1 snd_soc_simple_card
    snd_soc_ti_sdma        16384  1 snd_soc_davinci_mcasp
    snd_soc_core          172032  7 snd_soc_davinci_mcasp,snd_soc_simple_card_utils,snd_soc_ti_sdma,snd_soc_ti_edma,snd_soc_ti_udma,snd_soc_tlv320aic3262,snd_soc_simple_card
    snd_pcm_dmaengine      16384  1 snd_soc_core
    ac97_bus               16384  1 snd_soc_core
    snd_pcm                94208  4 snd_soc_davinci_mcasp,snd_pcm_dmaengine,snd_soc_simple_card_utils,snd_soc_core
    snd_timer              28672  1 snd_pcm
    snd                    61440  3 snd_timer,snd_soc_core,snd_pcm
    soundcore              16384  1 snd
    

    But no soundcards are found as shown below:-

    arecord -l
    arecord: device_list:274: no soundcards found...
    root@am57xx-evm:~# aplay -l  
    aplay: device_list:274: no soundcards found...
    

    PFA the dmesg output below:-

    [    0.000000] Booting Linux on physical CPU 0x0
    [    0.000000] Linux version 6.1.119-00016-gf3ed1c586d79-dirty (root@cdot-VirtualBox) (arm-oe-linux-gnueabi-gcc (GCC) 11.5.0, GNU ld (GNU Binutils) 2.38.20220708) #75 SMP PREEMPT Fri Aug 29 17:01:10 IST 2025
    [    0.000000] CPU: ARMv7 Processor [412fc0f2] revision 2 (ARMv7), cr=30c5387d
    [    0.000000] CPU: div instructions available: patching division code
    [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
    [    0.000000] OF: fdt: Machine model: TI AM5728 BeagleBoard-X15 rev C
    [    0.000000] Memory policy: Data cache writealloc
    [    0.000000] efi: UEFI not found.
    [    0.000000] Reserved memory: created CMA memory pool at 0x0000000095800000, size 56 MiB
    [    0.000000] OF: reserved mem: initialized node ipu2-memory@95800000, compatible id shared-dma-pool
    [    0.000000] Reserved memory: created CMA memory pool at 0x0000000099000000, size 64 MiB
    [    0.000000] OF: reserved mem: initialized node dsp1-memory@99000000, compatible id shared-dma-pool
    [    0.000000] Reserved memory: created DMA memory pool at 0x000000009d000000, size 32 MiB
    [    0.000000] OF: reserved mem: initialized node ipu1-memory@9d000000, compatible id shared-dma-pool
    [    0.000000] Reserved memory: created CMA memory pool at 0x000000009f000000, size 8 MiB
    [    0.000000] OF: reserved mem: initialized node dsp2-memory@9f000000, compatible id shared-dma-pool
    [    0.000000] cma: Reserved 64 MiB at 0x00000000ab800000
    [    0.000000] OMAP4: Map 0x00000000afd00000 to (ptrval) for dram barrier
    [    0.000000] Hit pending asynchronous external abort (FSR=0x00001211) during first unmask, this is most likely caused by a firmware/bootloader bug.
    [    0.000000] Zone ranges:
    [    0.000000]   DMA      [mem 0x0000000080000000-0x00000000afcfffff]
    [    0.000000]   Normal   empty
    [    0.000000]   HighMem  [mem 0x00000000afd00000-0x000000027fffffff]
    [    0.000000] Movable zone start for each node
    [    0.000000] Early memory node ranges
    [    0.000000]   node   0: [mem 0x0000000080000000-0x00000000956fffff]
    [    0.000000]   node   0: [mem 0x0000000095700000-0x00000000957fffff]
    [    0.000000]   node   0: [mem 0x0000000095800000-0x000000009cffffff]
    [    0.000000]   node   0: [mem 0x000000009d000000-0x000000009effffff]
    [    0.000000]   node   0: [mem 0x000000009f000000-0x00000000afcfffff]
    [    0.000000]   node   0: [mem 0x00000000b0000000-0x00000000feffffff]
    [    0.000000]   node   0: [mem 0x0000000200000000-0x000000027fffffff]
    [    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x000000027fffffff]
    [    0.000000] On node 0, zone HighMem: 768 pages in unavailable ranges
    [    0.000000] DRA752 ES2.0
    [    0.000000] clockdomain: ipu1_clkdm: powerdomain ipu_pwrdm does not exist
    [    0.000000] clockdomain: ipu_clkdm: powerdomain ipu_pwrdm does not exist
    [    0.000000] percpu: Embedded 16 pages/cpu s34324 r8192 d23020 u65536
    [    0.000000] pcpu-alloc: s34324 r8192 d23020 u65536 alloc=16*4096
    [    0.000000] pcpu-alloc: [0] 0 [0] 1 
    [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 1042182
    [    0.000000] Kernel command line: console=ttyS2,115200n8 root=PARTUUID=5c496148-02 rw rootfstype=ext4 rootwait
    [    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes, linear)
    [    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes, linear)
    [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
    [    0.000000] software IO TLB: area num 2.
    [    0.000000] software IO TLB: mapped [mem 0x00000000a3800000-0x00000000a7800000] (64MB)
    [    0.000000] Memory: 3758060K/4174848K available (12288K kernel code, 1468K rwdata, 3304K rodata, 2048K init, 308K bss, 220180K reserved, 196608K cma-reserved, 3325952K highmem)
    [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
    [    0.000000] trace event string verifier disabled
    [    0.000000] rcu: Preemptible hierarchical RCU implementation.
    [    0.000000] rcu: 	RCU event tracing is enabled.
    [    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=16 to nr_cpu_ids=2.
    [    0.000000] 	Trampoline variant of Tasks RCU enabled.
    [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
    [    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
    [    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
    [    0.000000] GIC: Using split EOI/Deactivate mode
    [    0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
    [    0.000000] OMAP clocksource: 32k_counter at 32768 Hz
    [    0.000000] clocksource: 32k_counter: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 58327039986419 ns
    [    0.000000] sched_clock: 32 bits at 33kHz, resolution 30517ns, wraps every 65535999984741ns
    [    0.001434] TI gptimer clockevent: always-on 32786 Hz at /ocp/interconnect@4ae00000/segment@10000/target-module@8000
    [    0.003143] TI gptimer percpu-dmtimer: 20000000 Hz at /ocp/interconnect@48800000/segment@0/target-module@2c000
    [    0.003326] TI gptimer percpu-dmtimer: 20000000 Hz at /ocp/interconnect@48800000/segment@0/target-module@2e000
    [    0.004241] Console: colour dummy device 80x30
    [    0.004272] Calibrating delay loop... 1993.93 BogoMIPS (lpj=9969664)
    [    0.062072] CPU: Testing write buffer coherency: ok
    [    0.062103] CPU0: Spectre v2: using ICIALLU workaround
    [    0.062103] CPU0: Spectre BHB: enabling loop workaround for all CPUs
    [    0.062103] pid_max: default: 32768 minimum: 301
    [    0.062255] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes, linear)
    [    0.062255] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes, linear)
    [    0.062896] /cpus/cpu@0 missing clock-frequency property
    [    0.062927] /cpus/cpu@1 missing clock-frequency property
    [    0.062927] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
    [    0.063568] cblist_init_generic: Setting adjustable number of callback queues.
    [    0.063598] cblist_init_generic: Setting shift to 1 and lim to 1.
    [    0.063690] Setting up static identity map for 0x80200000 - 0x80200138
    [    0.063781] rcu: Hierarchical SRCU implementation.
    [    0.063781] rcu: 	Max phase no-delay instances is 1000.
    [    0.065948] EFI services will not be available.
    [    0.066497] smp: Bringing up secondary CPUs ...
    [    0.126708] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
    [    0.126739] CPU1: Spectre v2: using ICIALLU workaround
    [    0.126831] smp: Brought up 1 node, 2 CPUs
    [    0.126831] SMP: Total of 2 processors activated (3994.41 BogoMIPS).
    [    0.126861] CPU: All CPU(s) started in HYP mode.
    [    0.126861] CPU: Virtualization extensions available.
    [    0.127288] devtmpfs: initialized
    [    0.150573] VFP support v0.3: implementor 41 architecture 4 part 30 variant f rev 0
    [    0.150756] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
    [    0.150787] futex hash table entries: 512 (order: 3, 32768 bytes, linear)
    [    0.155181] pinctrl core: initialized pinctrl subsystem
    [    0.155853] DMI not present or invalid.
    [    0.156249] NET: Registered PF_NETLINK/PF_ROUTE protocol family
    [    0.158050] DMA: preallocated 256 KiB pool for atomic coherent allocations
    [    0.159057] thermal_sys: Registered thermal governor 'step_wise'
    [    0.159088] cpuidle: using governor menu
    [    0.185333] platform ocp: Fixed dependency cycle(s) with /ocp/interconnect@4a000000/segment@0/target-module@8000/cm_core@0/clock@e00/clock@20
    [    0.185394] platform ocp: Fixed dependency cycle(s) with /ocp/interconnect@4a000000/segment@0/target-module@8000/cm_core@0/clock@700/clock@20
    [    0.188995] platform display: Fixed dependency cycle(s) with /ocp/target-module@58000000/dss@0
    [    0.190521] No ATAGs?
    [    0.190582] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers.
    [    0.190612] hw-breakpoint: maximum watchpoint size is 8 bytes.
    [    0.208587] reg-fixed-voltage fixedregulator-main_12v0: GPIO lookup for consumer (null)
    [    0.208587] reg-fixed-voltage fixedregulator-main_12v0: using device tree for GPIO lookup
    [    0.208618] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-main_12v0[0]'
    [    0.208618] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-main_12v0[0]'
    [    0.208648] reg-fixed-voltage fixedregulator-main_12v0: using lookup tables for GPIO lookup
    [    0.208648] reg-fixed-voltage fixedregulator-main_12v0: No GPIO consumer (null) found
    [    0.208892] reg-fixed-voltage fixedregulator-evm_5v0: GPIO lookup for consumer (null)
    [    0.208892] reg-fixed-voltage fixedregulator-evm_5v0: using device tree for GPIO lookup
    [    0.208923] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-evm_5v0[0]'
    [    0.208923] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-evm_5v0[0]'
    [    0.208953] reg-fixed-voltage fixedregulator-evm_5v0: using lookup tables for GPIO lookup
    [    0.208953] reg-fixed-voltage fixedregulator-evm_5v0: No GPIO consumer (null) found
    [    0.209564] iommu: Default domain type: Translated 
    [    0.209564] iommu: DMA domain TLB invalidation policy: strict mode 
    [    0.210906] SCSI subsystem initialized
    [    0.211059] libata version 3.00 loaded.
    [    0.211242] usbcore: registered new interface driver usbfs
    [    0.211273] usbcore: registered new interface driver hub
    [    0.211303] usbcore: registered new device driver usb
    [    0.211700] mc: Linux media interface: v0.10
    [    0.211761] pps_core: LinuxPPS API ver. 1 registered
    [    0.211761] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
    [    0.211761] PTP clock support registered
    [    0.211883] EDAC MC: Ver: 3.0.0
    [    0.213745] clocksource: Switched to clocksource 32k_counter
    [    0.221618] NET: Registered PF_INET protocol family
    [    0.221801] IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
    [    0.234405] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
    [    0.234405] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
    [    0.234436] TCP established hash table entries: 8192 (order: 3, 32768 bytes, linear)
    [    0.234497] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
    [    0.234710] TCP: Hash tables configured (established 8192 bind 8192)
    [    0.234802] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
    [    0.234832] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
    [    0.234954] NET: Registered PF_UNIX/PF_LOCAL protocol family
    [    0.235351] RPC: Registered named UNIX socket transport module.
    [    0.235382] RPC: Registered udp transport module.
    [    0.235382] RPC: Registered tcp transport module.
    [    0.235382] RPC: Registered tcp NFSv4.1 backchannel transport module.
    [    0.235382] PCI: CLS 0 bytes, default 64
    [    0.235778] armv7-pmu pmu: hw perfevents: no interrupt-affinity property, guessing.
    [    0.235931] hw perfevents: enabled with armv7_cortex_a15 PMU driver, 7 counters available
    [    0.236816] Initialise system trusted keyrings
    [    0.236999] workingset: timestamp_bits=30 max_order=20 bucket_order=0
    [    0.242584] squashfs: version 4.0 (2009/01/31) Phillip Lougher
    [    0.243194] NFS: Registering the id_resolver key type
    [    0.243225] Key type id_resolver registered
    [    0.243225] Key type id_legacy registered
    [    0.243316] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
    [    0.243316] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
    [    0.243347] ntfs: driver 2.1.32 [Flags: R/O].
    [    0.243865] Key type asymmetric registered
    [    0.243865] Asymmetric key parser 'x509' registered
    [    0.243988] bounce: pool size: 64 pages
    [    0.244079] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 246)
    [    0.244110] io scheduler mq-deadline registered
    [    0.244110] io scheduler kyber registered
    [    0.247161] omap_prm: probe of 4ae06500.prm failed with error -22
    [    0.293395] Serial: 8250/16550 driver, 5 ports, IRQ sharing enabled
    [    0.295410] STMicroelectronics ASC driver initialized
    [    0.296020] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4913, Function: panel_simple_init ****************************
    [    0.297393] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4918, Function: panel_simple_init ****************************
    [    0.297393] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4921, Function: panel_simple_init ****************************
    [    0.297424] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4924, Function: panel_simple_init ****************************
    [    0.297424] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4929, Function: panel_simple_init ****************************
    [    0.304565] brd: module loaded
    [    0.309234] loop: module loaded
    [    0.312438] mdio_bus fixed-0: GPIO lookup for consumer reset
    [    0.312469] mdio_bus fixed-0: using lookup tables for GPIO lookup
    [    0.312469] mdio_bus fixed-0: No GPIO consumer reset found
    [    0.313690] CAN device driver interface
    [    0.314086] e1000e: Intel(R) PRO/1000 Network Driver
    [    0.314086] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
    [    0.314147] igb: Intel(R) Gigabit Ethernet Network Driver
    [    0.314147] igb: Copyright (c) 2007-2014 Intel Corporation.
    [    0.314971] pegasus: Pegasus/Pegasus II USB Ethernet driver
    [    0.315002] usbcore: registered new interface driver pegasus
    [    0.315032] usbcore: registered new interface driver asix
    [    0.315063] usbcore: registered new interface driver ax88179_178a
    [    0.315093] usbcore: registered new interface driver cdc_ether
    [    0.315124] usbcore: registered new interface driver smsc75xx
    [    0.315185] usbcore: registered new interface driver smsc95xx
    [    0.315216] usbcore: registered new interface driver net1080
    [    0.315216] usbcore: registered new interface driver cdc_subset
    [    0.315246] usbcore: registered new interface driver zaurus
    [    0.315307] usbcore: registered new interface driver cdc_ncm
    [    0.316009] usbcore: registered new interface driver usb-storage
    [    0.316864] i2c_dev: i2c /dev entries driver
    [    0.319274] sdhci: Secure Digital Host Controller Interface driver
    [    0.319274] sdhci: Copyright(c) Pierre Ossman
    [    0.319458] Synopsys Designware Multimedia Card Interface Driver
    [    0.319671] sdhci-pltfm: SDHCI platform and OF driver helper
    [    0.320281] ledtrig-cpu: registered to indicate activity on CPUs
    [    0.320587] usbcore: registered new interface driver usbhid
    [    0.320587] usbhid: USB HID core driver
    [    0.323181] NET: Registered PF_INET6 protocol family
    [    0.324096] Segment Routing with IPv6
    [    0.324127] In-situ OAM (IOAM) with IPv6
    [    0.324188] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
    [    0.324676] NET: Registered PF_PACKET protocol family
    [    0.324676] can: controller area network core
    [    0.324737] NET: Registered PF_CAN protocol family
    [    0.324737] can: raw protocol
    [    0.324737] can: broadcast manager protocol
    [    0.324768] can: netlink gateway - max_hops=1
    [    0.324920] Key type dns_resolver registered
    [    0.324981] ThumbEE CPU extension supported.
    [    0.325012] Registering SWP/SWPB emulation handler
    [    0.325408] omap_voltage_late_init: Voltage driver support not added
    [    0.325408] Power Management for TI OMAP4+ devices.
    [    0.326171] Loading compiled-in X.509 certificates
    [    0.359436] platform 4a000000.interconnect: Fixed dependency cycle(s) with /ocp/interconnect@4a000000/segment@0/target-module@8000/cm_core@0/clock@d00/clock@20
    [    0.365295] pinctrl-single 4a003400.pinmux: 282 pins, size 1128
    [    0.387725] omap-dma-engine 4a056000.dma-controller: OMAP DMA engine driver (LinkedList1/2/3 supported)
    [    0.403961] gpio gpiochip0: (gpio-0-31): not an immutable chip, please consider fixing it!
    [    0.404144] gpio gpiochip0: (gpio-0-31): added GPIO chardev (254:0)
    [    0.404205] gpio gpiochip0: registered GPIOs 0 to 31 on gpio-0-31
    [    0.404235] OMAP GPIO hardware version 0.1
    [    0.406555] ti-sysc: probe of 4ae18000.target-module failed with error -16
    [    0.413543] printk: console [ttyS2] disabled
    [    0.413574] omap8250 48020000.serial: GPIO lookup for consumer rs485-term
    [    0.413574] omap8250 48020000.serial: using device tree for GPIO lookup
    [    0.413604] of_get_named_gpiod_flags: can't parse 'rs485-term-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@20000/serial@0[0]'
    [    0.413665] of_get_named_gpiod_flags: can't parse 'rs485-term-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@20000/serial@0[0]'
    [    0.413696] omap8250 48020000.serial: using lookup tables for GPIO lookup
    [    0.413696] omap8250 48020000.serial: No GPIO consumer rs485-term found
    [    0.413787] 48020000.serial: ttyS2 at MMIO 0x48020000 (irq = 100, base_baud = 3000000) is a 8250
    [    1.728790] printk: console [ttyS2] enabled
    [    1.740692] gpio gpiochip1: (gpio-32-63): not an immutable chip, please consider fixing it!
    [    1.749450] gpio gpiochip1: (gpio-32-63): added GPIO chardev (254:1)
    [    1.749542] gpio gpiochip1: registered GPIOs 32 to 63 on gpio-32-63
    [    1.750732] gpio gpiochip2: (gpio-64-95): not an immutable chip, please consider fixing it!
    [    1.759460] gpio gpiochip2: (gpio-64-95): added GPIO chardev (254:2)
    [    1.759521] gpio gpiochip2: registered GPIOs 64 to 95 on gpio-64-95
    [    1.760742] gpio gpiochip3: (gpio-96-127): not an immutable chip, please consider fixing it!
    [    1.769409] gpio gpiochip3: (gpio-96-127): added GPIO chardev (254:3)
    [    1.769470] gpio gpiochip3: registered GPIOs 96 to 127 on gpio-96-127
    [    1.770629] gpio gpiochip4: (gpio-128-159): not an immutable chip, please consider fixing it!
    [    1.779357] gpio gpiochip4: (gpio-128-159): added GPIO chardev (254:4)
    [    1.779418] gpio gpiochip4: registered GPIOs 128 to 159 on gpio-128-159
    [    1.780609] gpio gpiochip5: (gpio-160-191): not an immutable chip, please consider fixing it!
    [    1.789306] gpio gpiochip5: (gpio-160-191): added GPIO chardev (254:5)
    [    1.789367] gpio gpiochip5: registered GPIOs 160 to 191 on gpio-160-191
    [    1.790832] gpio gpiochip6: (gpio-192-223): not an immutable chip, please consider fixing it!
    [    1.799530] gpio gpiochip6: (gpio-192-223): added GPIO chardev (254:6)
    [    1.799591] gpio gpiochip6: registered GPIOs 192 to 223 on gpio-192-223
    [    1.800903] gpio gpiochip7: (gpio-224-255): not an immutable chip, please consider fixing it!
    [    1.809600] gpio gpiochip7: (gpio-224-255): added GPIO chardev (254:7)
    [    1.809661] gpio gpiochip7: registered GPIOs 224 to 255 on gpio-224-255
    [    1.811523] i2c i2c-2: GPIO lookup for consumer scl
    [    1.811523] i2c i2c-2: using device tree for GPIO lookup
    [    1.811553] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811584] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811614] i2c i2c-2: using lookup tables for GPIO lookup
    [    1.811614] i2c i2c-2: No GPIO consumer scl found
    [    1.811645] i2c i2c-2: GPIO lookup for consumer sda
    [    1.811645] i2c i2c-2: using device tree for GPIO lookup
    [    1.811645] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811706] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811737] i2c i2c-2: using lookup tables for GPIO lookup
    [    1.811737] i2c i2c-2: No GPIO consumer sda found
    [    1.812194] i2c 2-003c: Fixed dependency cycle(s) with /ocp/interconnect@48800000/target-module@190000/vip@0
    [    1.822387] omap_i2c 48060000.i2c: bus 2 rev0.12 at 400 kHz
    [    1.831665] omap8250 4806a000.serial: GPIO lookup for consumer rs485-term
    [    1.831695] omap8250 4806a000.serial: using device tree for GPIO lookup
    [    1.831695] of_get_named_gpiod_flags: can't parse 'rs485-term-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@6a000/serial@0[0]'
    [    1.831726] of_get_named_gpiod_flags: can't parse 'rs485-term-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@6a000/serial@0[0]'
    [    1.831787] omap8250 4806a000.serial: using lookup tables for GPIO lookup
    [    1.831787] omap8250 4806a000.serial: No GPIO consumer rs485-term found
    [    1.831817] 4806a000.serial: ttyS0 at MMIO 0x4806a000 (irq = 114, base_baud = 3000000) is a 8250
    [    1.843933] i2c i2c-0: GPIO lookup for consumer scl
    [    1.843933] i2c i2c-0: using device tree for GPIO lookup
    [    1.843963] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.843994] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.844024] i2c i2c-0: using lookup tables for GPIO lookup
    [    1.844055] i2c i2c-0: No GPIO consumer scl found
    [    1.844055] i2c i2c-0: GPIO lookup for consumer sda
    [    1.844055] i2c i2c-0: using device tree for GPIO lookup
    [    1.844085] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.844116] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.844146] i2c i2c-0: using lookup tables for GPIO lookup
    [    1.844146] i2c i2c-0: No GPIO consumer sda found
    [    1.844573] palmas 0-0058: Irq flag is 0x00000008
    [    1.876403] palmas 0-0058: Muxing GPIO 2b, PWM 0, LED 0
    [    1.908081] gpiochip_find_base: found new base at 504
    [    1.908294] gpio gpiochip8: (48070000.i2c:tps659038@58:tps659038_gpio): added GPIO chardev (254:8)
    [    1.908355] gpio gpiochip8: registered GPIOs 504 to 511 on 48070000.i2c:tps659038@58:tps659038_gpio
    [    1.909332] at24 0-0050: supply vcc not found, using dummy regulator
    [    1.916076] at24 0-0050: GPIO lookup for consumer wp
    [    1.916076] at24 0-0050: using device tree for GPIO lookup
    [    1.916076] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/eeprom@50[0]'
    [    1.916137] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/eeprom@50[0]'
    [    1.916168] at24 0-0050: using lookup tables for GPIO lookup
    [    1.916198] at24 0-0050: No GPIO consumer wp found
    [    1.916290] at24 0-0050: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
    [    1.923278] omap_i2c 48070000.i2c: bus 0 rev0.12 at 400 kHz
    [    1.930847] i2c i2c-1: GPIO lookup for consumer scl
    [    1.930847] i2c i2c-1: using device tree for GPIO lookup
    [    1.930877] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.930908] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.930938] i2c i2c-1: using lookup tables for GPIO lookup
    [    1.930938] i2c i2c-1: No GPIO consumer scl found
    [    1.930969] i2c i2c-1: GPIO lookup for consumer sda
    [    1.930969] i2c i2c-1: using device tree for GPIO lookup
    [    1.930969] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.931030] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.931060] i2c i2c-1: using lookup tables for GPIO lookup
    [    1.931060] i2c i2c-1: No GPIO consumer sda found
    [    1.931549] omap_i2c 48072000.i2c: bus 1 rev0.12 at 400 kHz
    [    1.939331] i2c i2c-3: GPIO lookup for consumer scl
    [    1.939361] i2c i2c-3: using device tree for GPIO lookup
    [    1.939361] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939422] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939453] i2c i2c-3: using lookup tables for GPIO lookup
    [    1.939453] i2c i2c-3: No GPIO consumer scl found
    [    1.939483] i2c i2c-3: GPIO lookup for consumer sda
    [    1.939483] i2c i2c-3: using device tree for GPIO lookup
    [    1.939483] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939514] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939575] i2c i2c-3: using lookup tables for GPIO lookup
    [    1.939575] i2c i2c-3: No GPIO consumer sda found
    [    1.939788] omap_i2c 4807a000.i2c: bus 3 rev0.12 at 400 kHz
    [    1.946929] i2c i2c-4: GPIO lookup for consumer scl
    [    1.946929] i2c i2c-4: using device tree for GPIO lookup
    [    1.946960] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.946990] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.947021] i2c i2c-4: using lookup tables for GPIO lookup
    [    1.947052] i2c i2c-4: No GPIO consumer scl found
    [    1.947052] i2c i2c-4: GPIO lookup for consumer sda
    [    1.947052] i2c i2c-4: using device tree for GPIO lookup
    [    1.947082] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.947113] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.947143] i2c i2c-4: using lookup tables for GPIO lookup
    [    1.947143] i2c i2c-4: No GPIO consumer sda found
    [    1.947692] edt_ft5x06 4-0038: supply vcc not found, using dummy regulator
    [    1.954681] omap_i2c 4807c000.i2c: bus 4 rev0.12 at 400 kHz
    [    1.954772] edt_ft5x06 4-0038: supply iovcc not found, using dummy regulator
    [    1.967498] omap_rng 48090000.rng: Random Number Generator ver. 20
    [    1.967651] edt_ft5x06 4-0038: GPIO lookup for consumer reset
    [    1.973754] edt_ft5x06 4-0038: using device tree for GPIO lookup
    [    1.973785] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.973815] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.973876] edt_ft5x06 4-0038: using lookup tables for GPIO lookup
    [    1.973907] edt_ft5x06 4-0038: No GPIO consumer reset found
    [    1.973907] edt_ft5x06 4-0038: GPIO lookup for consumer wake
    [    1.973907] edt_ft5x06 4-0038: using device tree for GPIO lookup
    [    1.973907] of_get_named_gpiod_flags: can't parse 'wake-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.973968] of_get_named_gpiod_flags: can't parse 'wake-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.974029] edt_ft5x06 4-0038: using lookup tables for GPIO lookup
    [    1.974029] edt_ft5x06 4-0038: No GPIO consumer wake found
    [    1.974151] random: crng init done
    [    1.999206] mdio_bus 48485000.mdio: GPIO lookup for consumer reset
    [    1.999206] mdio_bus 48485000.mdio: using device tree for GPIO lookup
    [    1.999237] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000[0]'
    [    1.999267] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000[0]'
    [    1.999328] mdio_bus 48485000.mdio: using lookup tables for GPIO lookup
    [    1.999328] mdio_bus 48485000.mdio: No GPIO consumer reset found
    [    2.006011] input: 4-0038 generic ft5x06 (8d) as /devices/platform/ocp/48000000.interconnect/48000000.interconnect:segment@0/4807c000.target-module/4807c000.i2c/i2c-4/4-0038/input/input0
    [    2.053771] davinci_mdio 48485000.mdio: davinci mdio revision 1.6, bus freq 1000000
    [    2.062286] mdio_bus 48485000.mdio:00: GPIO lookup for consumer reset
    [    2.062316] mdio_bus 48485000.mdio:00: using device tree for GPIO lookup
    [    2.062316] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@0[0]'
    [    2.062377] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@0[0]'
    [    2.062438] mdio_bus 48485000.mdio:00: using lookup tables for GPIO lookup
    [    2.062438] mdio_bus 48485000.mdio:00: No GPIO consumer reset found
    [    2.063293] mdio_bus 48485000.mdio:01: GPIO lookup for consumer reset
    [    2.063293] mdio_bus 48485000.mdio:01: using device tree for GPIO lookup
    [    2.063323] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@1[0]'
    [    2.063385] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@1[0]'
    [    2.063415] mdio_bus 48485000.mdio:01: using lookup tables for GPIO lookup
    [    2.063415] mdio_bus 48485000.mdio:01: No GPIO consumer reset found
    [    2.063598] davinci_mdio 48485000.mdio: phy[0]: device 48485000.mdio:00, driver unknown
    [    2.071655] davinci_mdio 48485000.mdio: phy[1]: device 48485000.mdio:01, driver unknown
    [    2.080291] cpsw-switch 48484000.switch: initialized cpsw ale version 1.4
    [    2.087127] cpsw-switch 48484000.switch: ALE Table size 1024
    [    2.092864] cpsw-switch 48484000.switch: cpts: overflow check period 500 (jiffies)
    [    2.100524] cpsw-switch 48484000.switch: CPTS: ref_clk_freq:266000000 calc_mult:4036623398 calc_shift:30 error:-1 nsec/sec
    [    2.111663] cpsw-switch 48484000.switch: Detected MACID = d0:03:eb:6c:3f:16
    [    2.118713] cpsw-switch 48484000.switch: Detected MACID = d0:03:eb:6c:3f:17
    [    2.127471] cpsw-switch 48484000.switch: initialized (regs 0x0000000048484000, pool size 256) hw_ver:0019010F 1.15 (0)
    [    2.149780] ti-sysc: probe of 4882c000.target-module failed with error -16
    [    2.157501] ti-sysc: probe of 4882e000.target-module failed with error -16
    [    2.168365] omap-mailbox 48840000.mailbox: omap mailbox rev 0x400
    [    2.175598] omap-mailbox 48842000.mailbox: omap mailbox rev 0x400
    [    2.190155] i2c 2-003c: Fixed dependency cycle(s) with /ocp/interconnect@48800000/target-module@190000/vip@0
    [    2.200164] platform 48990000.vip: Fixed dependency cycle(s) with /ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c
    [    2.216491] dra7-pcie 51000000.pcie: GPIO lookup for consumer (null)
    [    2.216491] dra7-pcie 51000000.pcie: using device tree for GPIO lookup
    [    2.216522] of_get_named_gpiod_flags: parsed 'gpios' property of node '/ocp/target-module@51000000/pcie@51000000[0]' - status (0)
    [    2.216552] gpio gpiochip3: Persistence not supported for GPIO 8
    [    2.216827] dra7-pcie 51000000.pcie: host bridge /ocp/target-module@51000000/pcie@51000000 ranges:
    [    2.225891] dra7-pcie 51000000.pcie:       IO 0x0020003000..0x0020012fff -> 0x0000000000
    [    2.234069] dra7-pcie 51000000.pcie:      MEM 0x0020013000..0x002fffffff -> 0x0020013000
    [    2.242431] dra7-pcie 51000000.pcie: iATU unroll: disabled
    [    2.247955] dra7-pcie 51000000.pcie: iATU regions: 16 ob, 4 ib, align 4K, limit 4G
    [    2.355712] dra7-pcie 51000000.pcie: PCIe Gen.2 x1 link up
    [    2.361358] dra7-pcie 51000000.pcie: PCI host bridge to bus 0000:00
    [    2.367675] pci_bus 0000:00: root bus resource [bus 00-ff]
    [    2.373199] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
    [    2.379425] pci_bus 0000:00: root bus resource [mem 0x20013000-0x2fffffff]
    [    2.386383] pci 0000:00:00.0: [104c:8888] type 01 class 0x060400
    [    2.392425] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
    [    2.398742] pci 0000:00:00.0: reg 0x14: [mem 0x00000000-0x0000ffff]
    [    2.405120] pci 0000:00:00.0: supports D1
    [    2.409149] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
    [    2.422058] PCI: bus0: Fast back to back transfers disabled
    [    2.427856] pci 0000:01:00.0: [8086:2526] type 00 class 0x028000
    [    2.433990] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00003fff 64bit]
    [    2.441162] pci 0000:01:00.0: PME# supported from D0 D3hot D3cold
    [    2.633880] PCI: bus1: Fast back to back transfers disabled
    [    2.639495] pci 0000:00:00.0: BAR 0: assigned [mem 0x20100000-0x201fffff]
    [    2.646362] pci 0000:00:00.0: BAR 8: assigned [mem 0x20200000-0x202fffff]
    [    2.653167] pci 0000:00:00.0: BAR 1: assigned [mem 0x20020000-0x2002ffff]
    [    2.660003] pci 0000:01:00.0: BAR 0: assigned [mem 0x20200000-0x20203fff 64bit]
    [    2.667419] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
    [    2.672668] pci 0000:00:00.0:   bridge window [mem 0x20200000-0x202fffff]
    [    2.679870] pcieport 0000:00:00.0: PME: Signaling with IRQ 138
    [    2.691833] edma 43300000.dma: memcpy is disabled
    [    2.699981] edma 43300000.dma: TI EDMA DMA engine driver
    [    2.711700] omap-iommu 40d01000.mmu: 40d01000.mmu registered
    [    2.719482] omap-iommu 40d02000.mmu: 40d02000.mmu registered
    [    2.726165] platform 40800000.dsp: Adding to iommu group 0
    [    2.733154] platform 58820000.ipu: Adding to iommu group 1
    [    2.738861] omap-iommu 58882000.mmu: 58882000.mmu registered
    [    2.746734] platform 55020000.ipu: Adding to iommu group 2
    [    2.752288] omap-iommu 55082000.mmu: 55082000.mmu registered
    [    2.764434] platform display: Fixed dependency cycle(s) with /ocp/target-module@58000000/dss@0
    [    2.773223] platform 58000000.dss: Fixed dependency cycle(s) with /display
    [    2.789031] omap-iommu 41501000.mmu: 41501000.mmu registered
    [    2.796325] omap-iommu 41502000.mmu: 41502000.mmu registered
    [    2.803131] platform 41000000.dsp: Adding to iommu group 3
    [    2.811187] ti-sysc 4ae06000.target-module: Failed to create device link (0x180) with ocp
    [    2.820892] gpio-clk clk_ov5640: GPIO lookup for consumer enable
    [    2.820922] gpio-clk clk_ov5640: using device tree for GPIO lookup
    [    2.820953] of_get_named_gpiod_flags: parsed 'enable-gpios' property of node '/clk_ov5640[0]' - status (0)
    [    2.820983] gpio gpiochip6: Persistence not supported for GPIO 18
    [    2.825073] reg-fixed-voltage fixedregulator-vdd_3v3: GPIO lookup for consumer (null)
    [    2.825103] reg-fixed-voltage fixedregulator-vdd_3v3: using device tree for GPIO lookup
    [    2.825103] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-vdd_3v3[0]'
    [    2.825134] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-vdd_3v3[0]'
    [    2.825195] reg-fixed-voltage fixedregulator-vdd_3v3: using lookup tables for GPIO lookup
    [    2.825225] reg-fixed-voltage fixedregulator-vdd_3v3: No GPIO consumer (null) found
    [    2.825592] reg-fixed-voltage fixedregulator-aic_dvdd: GPIO lookup for consumer (null)
    [    2.825592] reg-fixed-voltage fixedregulator-aic_dvdd: using device tree for GPIO lookup
    [    2.825622] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-aic_dvdd[0]'
    [    2.825622] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-aic_dvdd[0]'
    [    2.825622] reg-fixed-voltage fixedregulator-aic_dvdd: using lookup tables for GPIO lookup
    [    2.825653] reg-fixed-voltage fixedregulator-aic_dvdd: No GPIO consumer (null) found
    [    2.825897] reg-fixed-voltage fixedregulator-vtt: GPIO lookup for consumer (null)
    [    2.825897] reg-fixed-voltage fixedregulator-vtt: using device tree for GPIO lookup
    [    2.825897] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-vtt[0]'
    [    2.825927] of_get_named_gpiod_flags: parsed 'gpio' property of node '/fixedregulator-vtt[0]' - status (0)
    [    2.825958] gpio gpiochip1: Persistence not supported for GPIO 11
    [    2.855651] rtc-ds1307 2-006f: registered as rtc0
    [    2.860656] rtc-ds1307 2-006f: setting system clock to 2025-08-29T11:43:14 UTC (1756467794)
    [    2.869110] rtc-ds1307 2-006f: GPIO lookup for consumer wp
    [    2.869110] rtc-ds1307 2-006f: using device tree for GPIO lookup
    [    2.869140] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/rtc@6f[0]'
    [    2.869171] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/rtc@6f[0]'
    [    2.869201] rtc-ds1307 2-006f: using lookup tables for GPIO lookup
    [    2.869201] rtc-ds1307 2-006f: No GPIO consumer wp found
    [    2.872070] palmas-rtc 48070000.i2c:tps659038@58:tps659038_rtc: registered as rtc1
    [    2.881469] sdhci-omap 4809c000.mmc: GPIO lookup for consumer cd
    [    2.881500] sdhci-omap 4809c000.mmc: using device tree for GPIO lookup
    [    2.881500] of_get_named_gpiod_flags: parsed 'cd-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@9c000/mmc@0[0]' - status (0)
    [    2.881591] gpio gpiochip7: Persistence not supported for GPIO 27
    [    2.881591] omap_gpio 4805d000.gpio: Could not set line 27 debounce to 200000 microseconds (-22)
    [    2.881774] sdhci-omap 480b4000.mmc: GPIO lookup for consumer wp
    [    2.890472] sdhci-omap 4809c000.mmc: Got CD GPIO
    [    2.890777] sdhci-omap 480b4000.mmc: using device tree for GPIO lookup
    [    2.895172] sdhci-omap 4809c000.mmc: GPIO lookup for consumer wp
    [    2.895141] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@b4000/mmc@0[0]'
    [    2.895172] sdhci-omap 4809c000.mmc: using device tree for GPIO lookup
    [    2.895172] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@9c000/mmc@0[0]'
    [    2.895233] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@9c000/mmc@0[0]'
    [    2.895294] sdhci-omap 4809c000.mmc: using lookup tables for GPIO lookup
    [    2.895294] sdhci-omap 4809c000.mmc: No GPIO consumer wp found
    [    2.895629] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@b4000/mmc@0[0]'
    [    2.895690] sdhci-omap 480b4000.mmc: using lookup tables for GPIO lookup
    [    2.895690] sdhci-omap 480b4000.mmc: No GPIO consumer wp found
    [    2.896484] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 1147, Function: gpio_keys_init ****************************
    [    2.896514] sdhci-omap 480b4000.mmc: supply pbias not found, using dummy regulator
    [    2.909545] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 870, Function: gpio_keys_probe ****************************
    [    2.930023] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 788, Function: gpio_keys_get_devtree_pdata ****************************
    [    2.944091] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 523, Function: gpio_keys_setup_key ****************************
    [    2.957458] of_get_named_gpiod_flags: parsed 'gpios' property of node '/gpio-keys/button-user1[0]' - status (0)
    [    2.957489] gpio gpiochip0: Persistence not supported for GPIO 14
    [    2.957489] sdhci-omap 4809c000.mmc: no pinctrl state for ddr_3_3v mode
    [    2.957580] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 523, Function: gpio_keys_setup_key ****************************
    [    2.977539] of_get_named_gpiod_flags: parsed 'gpios' property of node '/gpio-keys/button-user2[0]' - status (0)
    [    2.977539] gpio gpiochip3: Persistence not supported for GPIO 6
    [    2.977752] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 523, Function: gpio_keys_setup_key ****************************
    [    2.991058] of_get_named_gpiod_flags: parsed 'gpios' property of node '/gpio-keys/button-user3[0]' - status (0)
    [    2.991088] gpio gpiochip6: Persistence not supported for GPIO 1
    [    2.991302] input: gpio-keys as /devices/platform/gpio-keys/input/input1
    [    2.998046] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 751, Function: gpio_keys_open ****************************
    [    3.010894] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 737, Function: gpio_keys_report_state ****************************
    [    3.016662] mmc1: SDHCI controller on 480b4000.mmc [480b4000.mmc] using ADMA
    [    3.024475] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 376, Function: gpio_keys_gpio_report_event ****************************
    [    3.031982] mmc0: SDHCI controller on 4809c000.mmc [4809c000.mmc] using ADMA
    [    3.045532] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 376, Function: gpio_keys_gpio_report_event ****************************
    [    3.045532] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 376, Function: gpio_keys_gpio_report_event ****************************
    [    3.081970] clk: Disabling unused clocks
    [    3.086791] Waiting for root device PARTUUID=5c496148-02...
    [    3.087432] mmc0: new high speed SDHC card at address 5048
    [    3.098236] mmcblk0: mmc0:5048 SD32G 29.7 GiB 
    [    3.105072]  mmcblk0: p1 p2
    [    3.174530] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Quota mode: disabled.
    [    3.183502] VFS: Mounted root (ext4 filesystem) on device 179:2.
    [    3.184234] mmc1: new DDR MMC card at address 0001
    [    3.194793] mmcblk1: mmc1:0001 032GB4 29.1 GiB 
    [    3.201263]  mmcblk1: p1 p2
    [    3.204864] mmcblk1boot0: mmc1:0001 032GB4 8.00 MiB 
    [    3.209960] devtmpfs: mounted
    [    3.210845] mmcblk1boot1: mmc1:0001 032GB4 8.00 MiB 
    [    3.218872] mmcblk1rpmb: mmc1:0001 032GB4 4.00 MiB, chardev (242:0)
    [    3.219085] Freeing unused kernel image (initmem) memory: 2048K
    [    3.231262] Run /sbin/init as init process
    [    3.235412]   with arguments:
    [    3.235412]     /sbin/init
    [    3.235412]   with environment:
    [    3.235412]     HOME=/
    [    3.235412]     TERM=linux
    [    3.624206] systemd[1]: systemd 250.5+ running in system mode (+PAM -AUDIT -SELINUX -APPARMOR +IMA -SMACK +SECCOMP -GCRYPT -GNUTLS -OPENSSL +ACL +BLKID -CURL -ELFUTILS -FIDO2 -IDN2 -IDN -IPTC +KMOD -LIBCRYPTSETUP +LIBFDISK -PCRE2 -PWQUALITY -P11KIT -QRENCODE -BZIP2 -LZ4 -XZ -ZLIB +ZSTD -BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=hybrid)
    [    3.656188] systemd[1]: Detected architecture arm.
    [    3.695068] systemd[1]: Hostname set to <am57xx-evm>.
    [    3.835510] systemd-sysv-generator[102]: SysV service '/etc/init.d/gdbserverproxy' lacks a native systemd unit file. Automatically generating a unit file for compatibility. Please update package to include a native systemd unit file, in order to make it more safe and robust.
    [    3.860412] systemd-sysv-generator[102]: SysV service '/etc/init.d/thermal-zone-init' lacks a native systemd unit file. Automatically generating a unit file for compatibility. Please update package to include a native systemd unit file, in order to make it more safe and robust.
    [    4.124328] systemd[1]: /lib/systemd/system/bt-enable.service:9: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [    4.189605] systemd[1]: /etc/systemd/system/sys-clock-drift.service:10: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [    4.211944] systemd[1]: /etc/systemd/system/sync-clocks.service:11: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [    4.292694] systemd[1]: Queued start job for default target Graphical Interface.
    [    4.302124] systemd[1]: Created slice Slice /system/getty.
    [    4.345214] systemd[1]: Created slice Slice /system/modprobe.
    [    4.384613] systemd[1]: Created slice Slice /system/serial-getty.
    [    4.424316] systemd[1]: Created slice User and Session Slice.
    [    4.464324] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
    [    4.503997] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
    [    4.544677] systemd[1]: Reached target Path Units.
    [    4.573913] systemd[1]: Reached target Remote File Systems.
    [    4.614013] systemd[1]: Reached target Slice Units.
    [    4.643951] systemd[1]: Reached target Swaps.
    [    4.686004] systemd[1]: Listening on RPCbind Server Activation Socket.
    [    4.723907] systemd[1]: Reached target RPC Port Mapper.
    [    4.774383] systemd[1]: Listening on Process Core Dump Socket.
    [    4.814270] systemd[1]: Listening on initctl Compatibility Named Pipe.
    [    4.903228] systemd[1]: Journal Audit Socket was skipped because of a failed condition check (ConditionSecurity=audit).
    [    4.914794] systemd[1]: Listening on Journal Socket (/dev/log).
    [    4.954376] systemd[1]: Listening on Journal Socket.
    [    4.984374] systemd[1]: Listening on Network Service Netlink Socket.
    [    5.024414] systemd[1]: Listening on udev Control Socket.
    [    5.064208] systemd[1]: Listening on udev Kernel Socket.
    [    5.104553] systemd[1]: Listening on User Database Manager Socket.
    [    5.144256] systemd[1]: Huge Pages File System was skipped because of a failed condition check (ConditionPathExists=/sys/kernel/mm/hugepages).
    [    5.204193] systemd[1]: Mounting POSIX Message Queue File System...
    [    5.246551] systemd[1]: Mounting Kernel Debug File System...
    [    5.276672] systemd[1]: Mounting Kernel Trace File System...
    [    5.335571] systemd[1]: Mounting Temporary Directory /tmp...
    [    5.367828] systemd[1]: Starting Create List of Static Device Nodes...
    [    5.406799] systemd[1]: Starting Load Kernel Module configfs...
    [    5.437133] systemd[1]: Starting Load Kernel Module drm...
    [    5.467193] systemd[1]: Starting Load Kernel Module fuse...
    [    5.508544] systemd[1]: Starting Start psplash boot splash screen...
    [    5.548126] systemd[1]: Starting RPC Bind...
    [    5.574188] systemd[1]: File System Check on Root Device was skipped because of a failed condition check (ConditionPathIsReadWrite=!/).
    [    5.587493] systemd[1]: systemd-journald.service: unit configures an IP firewall, but the local system does not support BPF/cgroup firewalling.
    [    5.600463] systemd[1]: (This warning is only shown for the first unit using IP firewalling.)
    [    5.610748] systemd[1]: Starting Journal Service...
    [    5.648071] systemd[1]: Starting Load Kernel Modules...
    [    5.675933] systemd[1]: Starting Generate network units from Kernel command line...
    [    5.716094] systemd[1]: Starting Remount Root and Kernel File Systems...
    [    5.744354] EXT4-fs (mmcblk0p2): re-mounted. Quota mode: disabled.
    [    5.756256] systemd[1]: Starting Coldplug All udev Devices...
    [    5.790191] systemd[1]: Started RPC Bind.
    [    5.824340] systemd[1]: Mounted POSIX Message Queue File System.
    [    5.864166] systemd[1]: Started Journal Service.
    [    6.439483] systemd-journald[115]: Received client request to flush runtime journal.
    [    7.253051] omap-sham 4b101000.sham: hw accel on OMAP rev 4.3
    [    7.268890] omap-rproc 58820000.ipu: assigned reserved memory node ipu1-memory@9d000000
    [    7.286041] omap-sham 4b101000.sham: will run requests pump with realtime priority
    [    7.292388] remoteproc remoteproc0: 58820000.ipu is available
    [    7.302062] omap-rproc 55020000.ipu: assigned reserved memory node ipu2-memory@95800000
    [    7.332305] remoteproc remoteproc1: 55020000.ipu is available
    [    7.342803] omap-rproc 40800000.dsp: assigned reserved memory node dsp1-memory@99000000
    [    7.355682] remoteproc remoteproc2: 40800000.dsp is available
    [    7.376678] omap-rproc 41000000.dsp: assigned reserved memory node dsp2-memory@9f000000
    [    7.413940] remoteproc remoteproc3: 41000000.dsp is available
    [    7.440490] omap-sham 42701000.sham: hw accel on OMAP rev 4.3
    [    7.459991] omap-sham 42701000.sham: will run requests pump with realtime priority
    [    7.794342] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: GPIO lookup for consumer id
    [    7.794342] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: using device tree for GPIO lookup
    [    7.794372] of_get_named_gpiod_flags: can't parse 'id-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]'
    [    7.794403] of_get_named_gpiod_flags: can't parse 'id-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]'
    [    7.794433] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: using lookup tables for GPIO lookup
    [    7.794433] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: No GPIO consumer id found
    [    7.794464] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: GPIO lookup for consumer vbus
    [    7.794464] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: using device tree for GPIO lookup
    [    7.794464] of_get_named_gpiod_flags: can't parse 'vbus-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]'
    [    7.794525] of_get_named_gpiod_flags: parsed 'vbus-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]' - status (0)
    [    7.794586] gpio gpiochip5: Persistence not supported for GPIO 21
    [    7.847198] remoteproc remoteproc0: powering up 58820000.ipu
    [    7.853576] remoteproc remoteproc1: powering up 55020000.ipu
    [    7.871429] remoteproc remoteproc1: Booting fw image dra7-ipu2-fw.xem4, size 3747228
    [    7.884857] remoteproc remoteproc0: Booting fw image dra7-ipu1-fw.xem4, size 4855436
    [    7.892669] omap-iommu 58882000.mmu: no fck found
    [    7.897430] omap-iommu 58882000.mmu: pwrdm_constraint failed to be set, status = -19
    [    7.905242] omap-iommu 58882000.mmu: 58882000.mmu: version 2.1
    [    7.913085] omap-iommu 55082000.mmu: 55082000.mmu: version 2.1
    [    7.921386] rproc-virtio rproc-virtio.2.auto: assigned reserved memory node ipu1-memory@9d000000
    [    7.952697] virtio_rpmsg_bus virtio0: rpmsg host is online
    [    7.960052] rproc-virtio rproc-virtio.2.auto: registered virtio0 (type 7)
    [    7.971191] remoteproc remoteproc0: remote processor 58820000.ipu is now up
    [    7.989318] virtio_rpmsg_bus virtio0: creating channel rpmsg-client-sample addr 0x32
    [    7.997344] pwm-backlight backlight: GPIO lookup for consumer enable
    [    7.997344] pwm-backlight backlight: using device tree for GPIO lookup
    [    7.997344] of_get_named_gpiod_flags: can't parse 'enable-gpios' property of node '/backlight[0]'
    [    7.997375] of_get_named_gpiod_flags: can't parse 'enable-gpio' property of node '/backlight[0]'
    [    7.997375] pwm-backlight backlight: using lookup tables for GPIO lookup
    [    7.997375] pwm-backlight backlight: No GPIO consumer enable found
    [    7.997436] pwm-backlight backlight: supply power not found, using dummy regulator
    [    8.008026] pwm-backlight backlight: invalid default brightness level: 8, using 7
    [    8.020843] virtio_rpmsg_bus virtio0: creating channel rpmsg-client-sample addr 0x33
    [    8.028991] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4571, Function: panel_simple_platform_probe ****************************
    [    8.045257] virtio_rpmsg_bus virtio0: creating channel rpmsg-omx addr 0x3c
    [    8.052246] virtio_rpmsg_bus virtio0: creating channel rpmsg-rpc addr 0x65
    [    8.059234] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 591, Function: panel_simple_probe ****************************
    [    8.106262] panel-simple display: supply power not found, using dummy regulator
    [    8.126647] rproc-virtio rproc-virtio.1.auto: assigned reserved memory node ipu2-memory@95800000
    [    8.126831] panel-simple display: GPIO lookup for consumer enable
    [    8.136505] virtio_rpmsg_bus virtio1: rpmsg host is online
    [    8.144195] rproc-virtio rproc-virtio.1.auto: registered virtio1 (type 7)
    [    8.151947] remoteproc remoteproc1: remote processor 55020000.ipu is now up
    [    8.160278] virtio_rpmsg_bus virtio1: creating channel rpmsg-rpc addr 0x65
    [    8.169677] virtio_rpmsg_bus virtio1: creating channel rpmsg-rpc addr 0x66
    [    8.187286] panel-simple display: using device tree for GPIO lookup
    [    8.187316] of_get_named_gpiod_flags: parsed 'enable-gpios' property of node '/display[0]' - status (0)
    [    8.187316] gpio gpiochip6: Persistence not supported for GPIO 12
    [    8.187347] panel-simple display: Specify missing connector_type
    [    8.208435] omap_rtc 48838000.rtc: registered as rtc2
    [    8.214630] omap_rtc 48838000.rtc: GPIO lookup for consumer wp
    [    8.214630] omap_rtc 48838000.rtc: using device tree for GPIO lookup
    [    8.214630] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48800000/segment@0/target-module@38000/rtc@0[0]'
    [    8.216094] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48800000/segment@0/target-module@38000/rtc@0[0]'
    [    8.216156] omap_rtc 48838000.rtc: using lookup tables for GPIO lookup
    [    8.216156] omap_rtc 48838000.rtc: No GPIO consumer wp found
    [    8.270263] omap-des 480a5000.des: OMAP DES hw accel rev: 2.2
    [    8.280975] videodev: Linux video capture interface: v2.00
    [    8.293945] omap-des 480a5000.des: will run requests pump with realtime priority
    [    8.381835] remoteproc remoteproc2: powering up 40800000.dsp
    [    8.394653] remoteproc remoteproc3: powering up 41000000.dsp
    [    8.404876] remoteproc remoteproc2: Booting fw image dra7-dsp1-fw.xe66, size 5535952
    [    8.412872] remoteproc remoteproc3: Booting fw image dra7-dsp2-fw.xe66, size 5536080
    [    8.426330] ahci-dwc 4a140000.sata: supply ahci not found, using dummy regulator
    [    8.434295] omap-iommu 40d01000.mmu: 40d01000.mmu: version 3.0
    [    8.440216] omap-iommu 40d02000.mmu: 40d02000.mmu: version 3.0
    [    8.446838] omap-iommu 41501000.mmu: 41501000.mmu: version 3.0
    [    8.452758] omap-iommu 41502000.mmu: 41502000.mmu: version 3.0
    [    8.471069] omap_wdt: OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
    [    8.478210] ahci-dwc 4a140000.sata: supply phy not found, using dummy regulator
    [    8.501403] ahci-dwc 4a140000.sata: supply target not found, using dummy regulator
    [    8.510742] ahci-dwc 4a140000.sata: forcing port_map 0x0 -> 0x1
    [    8.517364] ahci-dwc 4a140000.sata: AHCI 0001.0300 32 slots 1 ports 3 Gbps 0x1 impl platform mode
    [    8.547576] pinctrl-single 4a003400.pinmux: mux offset out of range: 0xffffe244 (0x468)
    [    8.556579] ahci-dwc 4a140000.sata: flags: 64bit ncq sntf pm led clo only pmp pio slum part ccc apst 
    [    8.568206] pinctrl-single 4a003400.pinmux: could not add functions for camera-gpio 4294959684x
    [    8.594482] rproc-virtio rproc-virtio.4.auto: assigned reserved memory node dsp2-memory@9f000000
    [    8.596954] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3850, Function: ov5640_probe ****************************
    [    8.616424] scsi host0: ahci-dwc
    [    8.617675] rproc-virtio rproc-virtio.3.auto: assigned reserved memory node dsp1-memory@99000000
    [    8.620208] ata1: SATA max UDMA/133 mmio [mem 0x4a140000-0x4a1410ff] port 0x100 irq 164
    [    8.639007] virtio_rpmsg_bus virtio2: rpmsg host is online
    [    8.647277] rproc-virtio rproc-virtio.4.auto: registered virtio2 (type 7)
    [    8.655242] remoteproc remoteproc3: remote processor 41000000.dsp is now up
    [    8.663055] virtio_rpmsg_bus virtio2: creating channel rpmsg-client-sample addr 0x32
    [    8.676940] virtio_rpmsg_bus virtio2: creating channel rpmsg-client-sample addr 0x33
    [    8.697357] virtio_rpmsg_bus virtio2: creating channel rpmsg-omx addr 0x3c
    [    8.705993] virtio_rpmsg_bus virtio2: creating channel rpmsg-rpc addr 0x65
    [    8.713500] virtio_rpmsg_bus virtio3: rpmsg host is online
    [    8.728393] omap-aes 4b500000.aes: OMAP AES hw accel rev: 3.3
    [    8.734374] vpe 489d0000.vpe: loading firmware vpdma-1b8.bin
    [    8.738372] rproc-virtio rproc-virtio.3.auto: registered virtio3 (type 7)
    [    8.760009] omap-aes 4b500000.aes: will run requests pump with realtime priority
    [    8.772949] ov5640 2-003c: GPIO lookup for consumer powerdown
    [    8.772949] ov5640 2-003c: using device tree for GPIO lookup
    [    8.772979] of_get_named_gpiod_flags: parsed 'powerdown-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c[0]' - status (0)
    [    8.773010] gpio gpiochip6: Persistence not supported for GPIO 17
    [    8.773040] ov5640 2-003c: GPIO lookup for consumer reset
    [    8.773040] ov5640 2-003c: using device tree for GPIO lookup
    [    8.773040] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c[0]'
    [    8.773071] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c[0]'
    [    8.773132] ov5640 2-003c: using lookup tables for GPIO lookup
    [    8.773132] ov5640 2-003c: No GPIO consumer reset found
    [    8.773162] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3814, Function: ov5640_get_regulators ****************************
    [    8.787902] vpe 489d0000.vpe: Device registered as /dev/video0
    [    8.796356] vip 48990000.vip: loading firmware vpdma-1b8.bin
    [    8.804840] ov5640 2-003c: supply DOVDD not found, using dummy regulator
    [    8.843749] remoteproc remoteproc2: remote processor 40800000.dsp is now up
    [    8.866943] ov5640 2-003c: supply AVDD not found, using dummy regulator
    [    8.878875] DSS: OMAP DSS rev 6.1
    [    8.912902] virtio_rpmsg_bus virtio3: creating channel rpmsg-client-sample addr 0x32
    [    8.924957] ov5640 2-003c: supply DVDD not found, using dummy regulator
    [    8.931915] omap-aes 4b700000.aes: OMAP AES hw accel rev: 3.3
    [    8.973297] omap-aes 4b700000.aes: will run requests pump with realtime priority
    [    8.992187] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3442, Function: ov5640_init_controls ****************************
    [    9.009002] virtio_rpmsg_bus virtio3: creating channel rpmsg-client-sample addr 0x33
    [    9.057434] virtio_rpmsg_bus virtio3: creating channel rpmsg-omx addr 0x3c
    [    9.096771] ata1: SATA link down (SStatus 0 SControl 300)
    [    9.102447] virtio_rpmsg_bus virtio3: creating channel rpmsg-rpc addr 0x65
    [    9.213562] omapdss_dss 58000000.dss: bound 58001000.dispc (ops dispc_component_ops [omapdrm])
    [    9.234161] vip 48990000.vip: VPDMA firmware loaded
    [    9.289001] dmm 4e000000.dmm: workaround for errata i878 in use
    [    9.367675] dmm 4e000000.dmm: initialized all PAT entries
    [    9.454223] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 476, Function: panel_simple_get_orientation ****************************
    [    9.490417] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3827, Function: ov5640_check_chip_id ****************************
    [    9.571411] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [    9.594970] vin3a: Port A: Using subdev ov5640 2-003c for capture
    [    9.649322] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [    9.761199] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 426, Function: panel_simple_get_modes ****************************
    [    9.797363] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [    9.877532] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [    9.958770] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.004669] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 253, Function: panel_simple_get_non_edid_modes ****************************
    [   10.090637] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.129913] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 221, Function: panel_simple_get_display_modes ****************************
    [   10.166595] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.234130] [drm] Enabling DMM ywrap scrolling
    [   10.247985] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 388, Function: panel_simple_prepare ****************************
    [   10.248016] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   10.248016] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 364, Function: panel_simple_resume ****************************
    [   10.248016] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 299, Function: panel_simple_wait ****************************
    [   10.267517] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.267517] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.267517] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.267517] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.267547] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.267547] **** vip: create_stream: V4L2_MBUS_BT656 ****
    [   10.365112] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 409, Function: panel_simple_enable ****************************
    [   10.365112] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   10.448699] Console: switching to colour frame buffer device 128x37
    [   10.699096] remoteproc remoteproc4: 4b234000.pru is available
    [   10.699768] remoteproc remoteproc5: 4b238000.pru is available
    [   10.706756] remoteproc remoteproc6: 4b2b8000.pru is available
    [   10.708068] remoteproc remoteproc7: 4b2b4000.pru is available
    [   10.900512] omapdrm omapdrm.0: [drm] fb0: omapdrmdrmfb frame buffer device
    [   10.935424] [drm] Initialized omapdrm 1.0.0 20110917 for omapdrm.0 on minor 0
    [   12.793945] EXT4-fs (mmcblk1p2): mounted filesystem with ordered data mode. Quota mode: disabled.
    [   13.575347] Bluetooth: Core ver 2.22
    [   13.623382] NET: Registered PF_BLUETOOTH protocol family
    [   13.673889] Bluetooth: HCI device and connection manager initialized
    [   13.683166] Bluetooth: HCI socket layer initialized
    [   13.693908] Bluetooth: L2CAP socket layer initialized
    [   13.713775] Bluetooth: SCO socket layer initialized
    [   13.755310] cfg80211: Loading compiled-in X.509 certificates for regulatory database
    [   13.920562] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
    [   13.933532] cfg80211: Loaded X.509 cert 'wens: 61c038651aabdcf94bd0ac7ff06c7248db18c600'
    [   14.093139] cpsw-switch 48484000.switch: starting ndev. mode: dual_mac
    [   14.132843] Initializing XFRM netlink socket
    [   14.171905] Generic PHY 48485000.mdio:01: attached PHY driver (mii_bus:phy_addr=48485000.mdio:01, irq=POLL)
    [   14.211944] cpsw-switch 48484000.switch: starting ndev. mode: dual_mac
    [   14.236145] Generic PHY 48485000.mdio:00: attached PHY driver (mii_bus:phy_addr=48485000.mdio:00, irq=POLL)
    [   14.265655] cpsw-switch 48484000.switch eth0: Link is Up - 100Mbps/Full - flow control off
    [   14.274047] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
    [   18.912567] systemd-journald[115]: Time jumped backwards, rotating.
    [   20.974670] platform sound0: deferred probe pending
    [   21.019317] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 426, Function: panel_simple_get_modes ****************************
    [   21.057464] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   21.083770] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 253, Function: panel_simple_get_non_edid_modes ****************************
    [   21.113769] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 221, Function: panel_simple_get_display_modes ****************************
    [   33.133972] ldousb: disabling

    In the dmesg output above I saw a message as below:-

    [   20.974670] platform sound0: deferred probe pending

    Why is the probing deferred even though the various drivers are loaded ?

    Below is the dtsi file contents in which I have done the entries for the device. 

    // SPDX-License-Identifier: GPL-2.0-only
    /*
     * Copyright (C) 2014-2016 Texas Instruments Incorporated - https://www.ti.com/
     */
    /dts-v1/;
    
    #include "am5728.dtsi"
    #include "am57xx-commercial-grade.dtsi"
    #include "dra74x-mmc-iodelay.dtsi"
    #include "dra74-ipu-dsp-common.dtsi"
    #include <dt-bindings/gpio/gpio.h>
    #include <dt-bindings/interrupt-controller/irq.h>
    
    / {
    	compatible = "ti,am572x-beagle-x15", "ti,am5728", "ti,dra742", "ti,dra74", "ti,dra7";
    
    	aliases {
    		rtc0 = &mcp_rtc;
    		rtc1 = &tps659038_rtc;
    		rtc2 = &rtc;
    		sound0 = &sound0;
    		//display0 = &hdmi0;
    		display0 = "/display";
    	};
    
    	gpio-keys {
                    compatible = "gpio-keys";
    
                    button-user1 {
                            gpios = <&gpio1 14 0>;
                            label = "VM_HOOK_INT";
    			linux,code = <103>;
                    };
    
                    button-user2 {
    			gpios = <&gpio2 6 1>;
                            label = "VM_KEYL_INT";
    			linux,code = <102>;
                    };
    
                    button-user3 {
    			gpios = <&gpio5 1 0>;
                            label = "VM_HEADSET_INT";
    			linux,code = <108>;
                    };
    
            };
    		
    	chosen {
    		stdout-path = &uart3;
    	};
    
    	memory@0 {
    		device_type = "memory";
    		reg = <0x0 0x80000000 0x0 0x80000000>;
    	};
    
    	main_12v0: fixedregulator-main_12v0 {
    		/* main supply */
    		compatible = "regulator-fixed";
    		regulator-name = "main_12v0";
    		regulator-min-microvolt = <12000000>;
    		regulator-max-microvolt = <12000000>;
    		regulator-always-on;
    		regulator-boot-on;
    	};
    
    	evm_5v0: fixedregulator-evm_5v0 {
    		/* Output of TPS54531D */
    		compatible = "regulator-fixed";
    		regulator-name = "evm_5v0";
    		regulator-min-microvolt = <5000000>;
    		regulator-max-microvolt = <5000000>;
    		vin-supply = <&main_12v0>;
    		regulator-always-on;
    		regulator-boot-on;
    	};
    
    	reserved-memory {
    		#address-cells = <2>;
    		#size-cells = <2>;
    		ranges;
    
    		ipu2_memory_region: ipu2-memory@95800000 {
    			compatible = "shared-dma-pool";
    			reg = <0x0 0x95800000 0x0 0x3800000>;
    			reusable;
    			status = "okay";
    		};
    
    		dsp1_memory_region: dsp1-memory@99000000 {
    			compatible = "shared-dma-pool";
    			reg = <0x0 0x99000000 0x0 0x4000000>;
    			reusable;
    			status = "okay";
    		};
    
    		ipu1_memory_region: ipu1-memory@9d000000 {
    			compatible = "shared-dma-pool";
    			reg = <0x0 0x9d000000 0x0 0x2000000>;
    			reusable;
    			status = "okay";
    		};
    
    		dsp2_memory_region: dsp2-memory@9f000000 {
    			compatible = "shared-dma-pool";
    			reg = <0x0 0x9f000000 0x0 0x800000>;
    			reusable;
    			status = "okay";
    		};
    	};
    
    	vdd_3v3: fixedregulator-vdd_3v3 {
    		compatible = "regulator-fixed";
    		regulator-name = "vdd_3v3";
    		vin-supply = <&regen1>;
    		regulator-min-microvolt = <3300000>;
    		regulator-max-microvolt = <3300000>;
    	};
    
    	aic_dvdd: fixedregulator-aic_dvdd {
    		compatible = "regulator-fixed";
    		regulator-name = "aic_dvdd_fixed";
    		vin-supply = <&vdd_3v3>;
    		regulator-min-microvolt = <1800000>;
    		regulator-max-microvolt = <1800000>;
    	};
    
    	vtt_fixed: fixedregulator-vtt {
    		/* TPS51200 */
    		compatible = "regulator-fixed";
    		regulator-name = "vtt_fixed";
    		vin-supply = <&smps3_reg>;
    		regulator-min-microvolt = <3300000>;
    		regulator-max-microvolt = <3300000>;
    		regulator-always-on;
    		regulator-boot-on;
    		enable-active-high;
    		gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>;
    	};
    
    	gpio_fan: gpio_fan {
    		/* Based on 5v 500mA AFB02505HHB */
    		compatible = "gpio-fan";
    		gpios =  <&tps659038_gpio 2 GPIO_ACTIVE_HIGH>;
    		gpio-fan,speed-map = <0     0>,
    				     <13000 1>;
    		#cooling-cells = <2>;
    	};
    
    	
    	clk_ov5640_fixed: clk_ov5640_fixed {
                            compatible = "fixed-clock";
                            #clock-cells = <0>;
                            clock-frequency = <24000000>;
                    };
    	clk_ov5640: clk_ov5640 {
                            compatible = "gpio-gate-clock";
                            #clock-cells = <0>;
                            clocks = <&clk_ov5640_fixed>;
                            enable-gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
                    };
    
    	lcd0: display {
                  compatible = "bolymin,btz070f-chc" ,"panel-dpi";
                  //compatible = "osddisplays,osd070t1718-19ts" ,"panel-dpi";
                  backlight = <&lcd_bl>;
                  enable-gpios = <&gpio5 12 GPIO_ACTIVE_HIGH>;
                  attr-gpios = <&gpio7 14 GPIO_ACTIVE_HIGH>; //LCD GPIO [AKSHI] changed in VIC2
                  label = "lcd";
    
    
                  port {
                       lcd_in: endpoint {
                               remote-endpoint = <&dpi_out>;
                               };
                  };
             };
    
             lcd_bl: backlight {
                     compatible = "pwm-backlight";
                     brightness-levels = <0 32 64 96 128 160 192 255>;
                     default-brightness-level = <8>;
                     pwms = <&ehrpwm0 0 50000 0>;
             };
    
    	sound0: sound0 {
    		compatible = "simple-audio-card";
    		simple-audio-card,name = "BeagleBoard-X15";
    		/*simple-audio-card,widgets =
    			"Line", "Line Out",
    			"Line", "Line In";
    		simple-audio-card,routing =
    			"Line Out",	"LLOUT",
    			"Line Out",	"RLOUT",
    			"MIC2L",	"Line In",
    			"MIC2R",	"Line In";*/
    		simple-audio-card,format = "i2s";
    		simple-audio-card,bitclock-master = <&sound0_master>;
    		simple-audio-card,frame-master = <&sound0_master>;
    		//simple-audio-card,bitclock-inversion;
    
    		sound0_cpu: simple-audio-card,cpu {
    			sound-dai = <&mcasp3>;
    	        };
    		sound0_master: simple-audio-card,codec {
    			sound-dai = <&tlv320aic3262>;
    			clocks = <&clkout2_clk>;
    		};
    	};
    };
    
    &i2c1 {
    	status = "okay";
    	clock-frequency = <400000>;
    
    	tps659038: tps659038@58 {
    		compatible = "ti,tps659038";
    		reg = <0x58>;
    		interrupt-parent = <&gpio1>;
    		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
    
    		#interrupt-cells = <2>;
    		interrupt-controller;
    
    		ti,system-power-controller;
    		ti,palmas-override-powerhold;
    
    		tps659038_pmic {
    			compatible = "ti,tps659038-pmic";
    
    			regulators {
    				smps12_reg: smps12 {
    					/* VDD_MPU */
    					regulator-name = "smps12";
    					regulator-min-microvolt = < 850000>;
    					regulator-max-microvolt = <1250000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				smps3_reg: smps3 {
    					/* VDD_DDR */
    					regulator-name = "smps3";
    					regulator-min-microvolt = <1350000>;
    					regulator-max-microvolt = <1350000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				smps45_reg: smps45 {
    					/* VDD_DSPEVE, VDD_IVA, VDD_GPU */
    					regulator-name = "smps45";
    					regulator-min-microvolt = < 850000>;
    					regulator-max-microvolt = <1250000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				smps6_reg: smps6 {
    					/* VDD_CORE */
    					regulator-name = "smps6";
    					regulator-min-microvolt = <850000>;
    					regulator-max-microvolt = <1150000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				/* SMPS7 unused */
    
    				smps8_reg: smps8 {
    					/* VDD_1V8 */
    					regulator-name = "smps8";
    					regulator-min-microvolt = <1800000>;
    					regulator-max-microvolt = <1800000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				/* SMPS9 unused */
    
    				ldo1_reg: ldo1 {
    					/* VDD_SD / VDDSHV8  */
    					regulator-name = "ldo1";
    					regulator-min-microvolt = <1800000>;
    					regulator-max-microvolt = <3300000>;
    					regulator-boot-on;
    					regulator-always-on;
    				};
    
    				ldo2_reg: ldo2 {
    					/* VDD_SHV5 */
    					regulator-name = "ldo2";
    					regulator-min-microvolt = <3300000>;
    					regulator-max-microvolt = <3300000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				ldo3_reg: ldo3 {
    					/* VDDA_1V8_PHYA */
    					regulator-name = "ldo3";
    					regulator-min-microvolt = <1800000>;
    					regulator-max-microvolt = <1800000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				ldo4_reg: ldo4 {
    					/* VDDA_1V8_PHYB */
    					regulator-name = "ldo4";
    					regulator-min-microvolt = <1800000>;
    					regulator-max-microvolt = <1800000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				ldo9_reg: ldo9 {
    					/* VDD_RTC */
    					regulator-name = "ldo9";
    					regulator-min-microvolt = <1050000>;
    					regulator-max-microvolt = <1050000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				ldoln_reg: ldoln {
    					/* VDDA_1V8_PLL */
    					regulator-name = "ldoln";
    					regulator-min-microvolt = <1800000>;
    					regulator-max-microvolt = <1800000>;
    					regulator-always-on;
    					regulator-boot-on;
    				};
    
    				ldousb_reg: ldousb {
    					/* VDDA_3V_USB: VDDA_USBHS33 */
    					regulator-name = "ldousb";
    					regulator-min-microvolt = <3300000>;
    					regulator-max-microvolt = <3300000>;
    					regulator-boot-on;
    				};
    
    				regen1: regen1 {
    					/* VDD_3V3_ON */
    					regulator-name = "regen1";
    					regulator-boot-on;
    					regulator-always-on;
    				};
    			};
    		};
    
    		tps659038_rtc: tps659038_rtc {
    			compatible = "ti,palmas-rtc";
    			interrupt-parent = <&tps659038>;
    			interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
    			wakeup-source;
    		};
    
    		tps659038_pwr_button: tps659038_pwr_button {
    			compatible = "ti,palmas-pwrbutton";
    			interrupt-parent = <&tps659038>;
    			interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
    			wakeup-source;
    			ti,palmas-long-press-seconds = <12>;
    		};
    
    		tps659038_gpio: tps659038_gpio {
    			compatible = "ti,palmas-gpio";
    			gpio-controller;
    			#gpio-cells = <2>;
    		};
    
    		extcon_usb2: tps659038_usb {
    			compatible = "ti,palmas-usb-vid";
    			ti,enable-vbus-detection;
    			vbus-gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>;
    		};
    
    	};
    
    	/*tmp102: tmp102@48 {
    		compatible = "ti,tmp102";
    		reg = <0x48>;
    		interrupt-parent = <&gpio7>;
    		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
    		#thermal-sensor-cells = <1>;
    	};*/
    
    
    	eeprom: eeprom@50 {
    		compatible = "atmel,24c256";
    		reg = <0x50>;
    	};
    };
    
    //AKSHI
    &i2c2 {
    	status = "okay";
    	clock-frequency = <400000>;
    	
    	//changed to 6_19 from 7_8 in VIC2
    	proc_temp: lm75@48 {
                       compatible = "national,lm75a";
                       reg = <0x48>;
    	           interrupt-parent = <&gpio6>;
    		   interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
    		   #thermal-sensor-cells = <1>;
            };
    
            handset_temp: lm75@49 {
                       compatible = "national,lm75a";
                       reg = <0x49>;
    	           interrupt-parent = <&gpio6>;
    		   interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
    		   #thermal-sensor-cells = <0>;
            };
    
    };
    
    
    
    &vin3a {
    	
    	ti,vip-instance = <1>;       // VIP2 = instance 1
    	ti,vip-port = <0>;           // Port A
    	ti,vip-channels = <0>;       // Channel 0
    	status = "okay";
            vin3a_ep: endpoint {
                    remote-endpoint = <&cam>;
                    slave-mode;
            };
    };
    
    &vip2 {
            status = "okay";
    };
    
    &i2c3 {
            status = "okay";
            clock-frequency = <400000>;
    
    	mcp_rtc: rtc@6f {
    		compatible = "microchip,mcp7941x";
    		reg = <0x6f>;
    		interrupts-extended = <&crossbar_mpu GIC_SPI 2 IRQ_TYPE_EDGE_RISING>,
    				      <&dra7_pmx_core 0x424>;
    		interrupt-names = "irq", "wakeup";
    
    		vcc-supply = <&vdd_3v3>;
    		wakeup-source;
    	};
    
    
            ov5640@3c {
                    compatible = "ovti,ov5640";
                    reg = <0x3c>;
                    clock-names = "xclk";
                    clocks = <&clk_ov5640>;
    		pinctrl-names = "default";
                    pinctrl-0 = <&camera_gpio>;
    		powerdown-gpios = <&gpio5 17 GPIO_ACTIVE_HIGH>;
    
                    port {
                            cam: endpoint {
                                    bus-width = <8>;
                                    data-shift = <2>;
                                    hsync-active = <1>;
                                    vsync-active = <1>;
                                    pclk-sample = <1>;
                                    remote-endpoint = <&vin3a_ep>;
                            };
                    };
            };
    
    };
    
    &i2c4 {
    status = "okay";
    clock-frequency = <400000>;
    
    	tlv320aic3262: tlv320aic3x@18 {
    		#sound-dai-cells = <0>;
    		compatible = "ti,aic3262";
    		reg = <0x18>;
    		assigned-clocks = <&clkoutmux2_clk_mux>;
    		assigned-clock-parents = <&sys_clk2_dclk_div>;
    
    		status = "okay";
    		adc-settle-ms = <40>;
    
    		//AVDD-supply = <&vdd_3v3>;
    		//IOVDD-supply = <&vdd_3v3>;
    		//DRVDD-supply = <&vdd_3v3>;
    		//DVDD-supply = <&aic_dvdd>;
    	};
    };
    
    &ehrpwm0 {
            status = "okay";
    };
    
    &epwmss0 {
            status = "okay";
    };
    
    
    /* [00] ::  Added Touch panel entries */
    &i2c5 {
            status = "okay";
            clock-frequency = <400000>;
    
            polytouch: edt-ft5x06@38 {
                    compatible = "edt,edt-ft5x06";
                    reg = <0x38>;
                    attb-gpio = <&gpio5 9 GPIO_ACTIVE_HIGH>;
                    interrupt-parent = <&gpio5>;
                    interrupts = <9 0>;
            //reset-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>;
            //wake-gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>;
    /* AKSHI*/
                    threshold = <20>;
                    touchscreen-size-x = <1024>;
                    touchscreen-size-y = <600>;
                    wakeup-source;
        };
    
    };
    
    
    /*&gpio7_target {
    	ti,no-reset-on-init;
    	ti,no-idle-on-init;
    };*/
    
    
    &cpu0 {
    	vdd-supply = <&smps12_reg>;
    	voltage-tolerance = <1>;
    };
    
    &uart3 {
    	status = "okay";
    	interrupts-extended = <&crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
    			      <&dra7_pmx_core 0x3f8>;
    };
    
    &davinci_mdio_sw {
    	phy0: ethernet-phy@0 {
    		reg = <0>;
    	};
    
    	phy1: ethernet-phy@1 {
    		reg = <1>;
    	};
    };
    
    &mac_sw {
    	status = "okay";
    	dual_emac;
    };
    
    &cpsw_port0 {
    	phy-handle = <&phy0>;
    	//phy-mode = "rgmii-rxid";
    	phy-mode = "rgmii";
    	ti,dual-emac-pvid = <1>;
    };
    
    &cpsw_port1 {
    	phy-handle = <&phy1>;
    	//phy-mode = "rgmii-rxid";
    	phy-mode = "rgmii";
    	ti,dual-emac-pvid = <2>;
    };
    
    &mmc1 {
    	status = "okay";
    
    	pinctrl-names = "default";
    	pinctrl-0 = <&mmc1_pins_default>;
    
    	bus-width = <4>;
    	cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; /* gpio 219 */
    	no-1-8-v;
    };
    
    &mmc2 {
    	status = "okay";
    
    	pinctrl-names = "default";
    	pinctrl-0 = <&mmc2_pins_default>;
    
    	vmmc-supply = <&vdd_3v3>;
    	vqmmc-supply = <&vdd_3v3>;
    	bus-width = <8>;
    	non-removable;
    	no-1-8-v;
    };
    
    &sata {
    	status = "okay";
    };
    
    &usb2_phy1 {
    	phy-supply = <&ldousb_reg>;
    };
    
    &usb2_phy2 {
    	phy-supply = <&ldousb_reg>;
    };
    
    &usb1 {
    	dr_mode = "host";
    	status = "disabled"; 
    };
    
    &omap_dwc3_2 {
    	extcon = <&extcon_usb2>;
    };
    
    &usb2 {
    	/*
    	 * Stand alone usage is peripheral only.
    	 * However, with some resistor modifications
    	 * this port can be used via expansion connectors
    	 * as "host" or "dual-role". If so, provide
    	 * the necessary dr_mode override in the expansion
    	 * board's DT.
    	 */
    	dr_mode = "peripheral";
    	status = "disabled";
    };
    
    &cpu_trips {
    	cpu_alert1: cpu_alert1 {
    		temperature = <50000>; /* millicelsius */
    		hysteresis = <2000>; /* millicelsius */
    		type = "active";
    	};
    };
    
    &cpu_cooling_maps {
    	map1 {
    		trip = <&cpu_alert1>;
    		cooling-device = <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
    	};
    };
    
    &thermal_zones {
    	board_thermal: board_thermal {
    		polling-delay-passive = <1250>; /* milliseconds */
    		polling-delay = <1500>; /* milliseconds */
    
    				/* sensor       ID */
    		thermal-sensors = <&proc_temp 0>;
    
    		board_trips: trips {
    			board_alert0: board_alert {
    				temperature = <40000>; /* millicelsius */
    				hysteresis = <2000>; /* millicelsius */
    				type = "active";
    			};
    
    			board_crit: board_crit {
    				temperature = <105000>; /* millicelsius */
    				hysteresis = <0>; /* millicelsius */
    				type = "critical";
    			};
    		};
    
    		board_cooling_maps: cooling-maps {
    			map0 {
    				trip = <&board_alert0>;
    				cooling-device =
    				  <&gpio_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
    			};
    		};
           };
    };
    
    &gpu {
    	status = "ok";
    };
    
    &dss {
            status = "okay";
            vdda_video-supply = <&ldoln_reg>;
            ports {
                    #address-cells = <1>;
                    #size-cells = <0>;
    
                    port {
                            reg = <0>;
                            dpi_out: endpoint {
                                    data-lines = <24>;
                                    remote-endpoint = <&lcd_in>;
                            };
                    };
            };
    };
    
    
    /*&hdmi {
    	status = "okay";
    	vdda-supply = <&ldo4_reg>;
    
    	port {
    		hdmi_out: endpoint {
    			remote-endpoint = <&tpd12s015_in>;
    		};
    	};
    };*/
    
    &pcie1_rc {
    	status = "okay";
    	gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
    };
    
    &mcasp3 {
    	#sound-dai-cells = <0>;
    	assigned-clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 24>;
    	assigned-clock-parents = <&sys_clkin2>;
    	status = "okay";
    
    	op-mode = <0>;	/* MCASP_IIS_MODE */
    	tdm-slots = <2>;
    	/* 4 serializers */
    	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
    		1 2 0 0
    	>;
    	tx-num-evt = <32>;
    	rx-num-evt = <32>;
    };
    
    &ipu2 {
    	status = "okay";
    	memory-region = <&ipu2_memory_region>;
    };
    
    &ipu1 {
    	status = "okay";
    	memory-region = <&ipu1_memory_region>;
    };
    
    &dsp1 {
    	status = "okay";
    	memory-region = <&dsp1_memory_region>;
    };
    
    &dsp2 {
    	status = "okay";
    	memory-region = <&dsp2_memory_region>;
    };
    
    &pruss1_mdio {
    	status = "disabled";
    };
    
    &pruss2_mdio {
    	status = "disabled";
    };
    
    #include "dra7-ipu-common-early-boot.dtsi"

     Please help. Thanks!

    -Vishal

  • Hi  ,

    Please reply at the earliest. We are stuck with this driver probe issue.

    Thanks!

    -Vishal 

  •   I am checking it - will get back to you asap. Just curious, what was the kernel version used earlier ? and did we not have the device tree file earlier ? please let me know 

  • HI  ,

     I am checking it - will get back to you asap. 

    Sure, please! Thanks!

    Just curious, what was the kernel version used earlier ?

    In 6.03 SDK we used its default 4.19.x kernel. 

    and did we not have the device tree file earlier ?

    No we did have DTS files earlier too. 

  • I've updated patch v2. Please check. I have tested for probe issue.

  •   , 

    I've updated patch v2.

    Ok, I will do it as a fresh patch on TI's Linux  SDK 9.03's 6.1 kernel.

    I have tested for probe issue.

    What exactly did you change to get the probe working? If you could explain in a line or two.

    -Vishal

  • Hi Vishal

    - Added support for device tree based i2c core mfd driver probe.

    - Due to update to kernel version, some changes were required for DAPM widgets and routing in codec driver as well. I have included that change. 

    please test and let me know if there are issues. thanks 

    Niranjan 

  •   ,

    I copied your updated contents to test2.patch  and ran the command git am test2.patch (from the linux kernel directory) as a fresh patch and not above patch1 that you gave earlier.

    I am getting this error below.

    Applying: add tlv320aic3262 driver
    .git/rebase-apply/patch:1245: trailing whitespace.
    #define AIC3262_JACK_TYPE_MASK		(0b00110000) 
    error: patch failed: drivers/mfd/Kconfig:1208
    error: drivers/mfd/Kconfig: patch does not apply
    error: patch failed: drivers/mfd/Makefile:32
    error: drivers/mfd/Makefile: patch does not apply
    .git/rebase-apply/patch:1481: new blank line at EOF.
    +
    error: patch failed: sound/soc/codecs/Makefile:331
    error: sound/soc/codecs/Makefile: patch does not apply
    .git/rebase-apply/patch:3499: new blank line at EOF.
    +
    Patch failed at 0001 add tlv320aic3262 driver
    hint: Use 'git am --show-current-patch=diff' to see the failed patch
    When you have resolved this problem, run "git am --continue".
    If you prefer to skip this patch, run "git am --skip" instead.
    To restore the original branch and stop patching, run "git am --abort".
    

    Please help. May be test2.patch contents have something missing or my procedure is a miss!

    -Vishal

  •   ,

    I copied your updated contents to test2.patch  and ran the command git am test2.patch (from the linux kernel directory) as a fresh patch and not above patch1 that you gave earlier.

    I am getting this error below.

    Applying: add tlv320aic3262 driver
    .git/rebase-apply/patch:1245: trailing whitespace.
    #define AIC3262_JACK_TYPE_MASK		(0b00110000) 
    error: patch failed: drivers/mfd/Kconfig:1208
    error: drivers/mfd/Kconfig: patch does not apply
    error: patch failed: drivers/mfd/Makefile:32
    error: drivers/mfd/Makefile: patch does not apply
    .git/rebase-apply/patch:1481: new blank line at EOF.
    +
    error: patch failed: sound/soc/codecs/Makefile:331
    error: sound/soc/codecs/Makefile: patch does not apply
    .git/rebase-apply/patch:3499: new blank line at EOF.
    +
    Patch failed at 0001 add tlv320aic3262 driver
    hint: Use 'git am --show-current-patch=diff' to see the failed patch
    When you have resolved this problem, run "git am --continue".
    If you prefer to skip this patch, run "git am --skip" instead.
    To restore the original branch and stop patching, run "git am --abort".
    

    Please help. May be test2.patch contents have some extra spaces!

    Please give the correct contents of test2.patch.

    Thanks

    -Vishal

  • Could you please try with patch -p 1 < test2.patch and see if it works. I don't have the exact build setup which you have. If there are some .rej files generated, some manual changes might be required. thanks - Niranjan

  • Hi  ,

    I used the command below to apply the patch and then manually resolved the .rej file(s) issues.

    patch -p1 --verbose --forward < test2.patch

    Here is the git status command output

    /opt/ti-processor-sdk-linux-am57xx-evm-09_03_06_05/board-support/ti-linux-kernel-6.1.119+gitAUTOINC+e4e8b16e66-ti# git status
    On branch ti_audio_patch2
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git restore <file>..." to discard changes in working directory)
    	modified:   .config
    	modified:   drivers/mfd/Kconfig
    	modified:   drivers/mfd/Makefile
    	modified:   sound/soc/codecs/Kconfig
    	modified:   sound/soc/codecs/Makefile
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
    	drivers/mfd/tlv320aic3xxx-core.c
    	drivers/mfd/tlv320aic3xxx-i2c.c
    	drivers/mfd/tlv320aic3xxx-irq.c
    	drivers/mfd/tlv320aic3xxx-spi.c
    	include/linux/mfd/tlv320aic3262-registers.h
    	include/linux/mfd/tlv320aic3xxx-core.h
    	sound/soc/codecs/aic3xxx/
    	sound/soc/codecs/tlv320aic326x.c
    	sound/soc/codecs/tlv320aic326x.h
    

    Then after enabling the audio codec driver in .config and running make -j12 in my kernel directory I am getting the following error.

    root@cdot-VirtualBox:/opt/ti-processor-sdk-linux-am57xx-evm-09_03_06_05/board-support/ti-linux-kernel-6.1.119+gitAUTOINC+e4e8b16e66-ti# make -j12
      CALL    scripts/checksyscalls.sh
      CC      drivers/ptp/ptp_clock.o
      CC      drivers/mfd/tlv320aic3xxx-i2c.o
      CC      drivers/power/reset/brcm-kona-reset.o
      CC      drivers/power/supply/power_supply_core.o
      CC      drivers/power/reset/brcmstb-reboot.o
      CC      drivers/power/reset/gpio-poweroff.o
    drivers/mfd/tlv320aic3xxx-i2c.c:132:27: error: initialization of 'int (*)(struct i2c_client *, const struct i2c_device_id *)' from incompatible pointer type 'int (*)(struct i2c_client *)' [-Werror=incompatible-pointer-types]
      132 |         .probe          = aic3xxx_i2c_probe,
          |                           ^~~~~~~~~~~~~~~~~
    drivers/mfd/tlv320aic3xxx-i2c.c:132:27: note: (near initialization for 'aic3xxx_i2c_driver.probe')
    cc1: some warnings being treated as errors
      CC      drivers/power/supply/power_supply_sysfs.o
    make[3]: *** [scripts/Makefile.build:250: drivers/mfd/tlv320aic3xxx-i2c.o] Error 1
    make[2]: *** [scripts/Makefile.build:505: drivers/mfd] Error 2
    make[2]: *** Waiting for unfinished jobs....
      CC      drivers/power/reset/gpio-restart.o
      CC      drivers/ptp/ptp_chardev.o
      CC      drivers/power/supply/power_supply_leds.o
      CC      drivers/power/reset/vexpress-poweroff.o
      CC      drivers/ptp/ptp_sysfs.o
      CC      drivers/power/reset/keystone-reset.o
      CC      drivers/power/supply/power_supply_hwmon.o
      CC      drivers/power/supply/act8945a_charger.o
      CC      drivers/power/supply/sbs-battery.o
      CC      drivers/power/supply/tps65090-charger.o
      CC      drivers/power/reset/syscon-reboot.o
      CC      drivers/ptp/ptp_vclock.o
      CC      drivers/ptp/ptp_kvm_arm.o
      CC      drivers/power/reset/syscon-poweroff.o
      CC      drivers/ptp/ptp_kvm_common.o
      CC [M]  drivers/power/supply/cpcap-battery.o
      CC [M]  drivers/power/supply/bq27xxx_battery.o
      AR      drivers/power/reset/built-in.a
      CC [M]  sound/soc/codecs/tlv320aic326x.o
      CC [M]  drivers/power/supply/bq27xxx_battery_i2c.o
      CC [M]  drivers/power/supply/max17040_battery.o
      CC [M]  drivers/power/supply/max17042_battery.o
      CC [M]  drivers/power/supply/cpcap-charger.o
      CC [M]  drivers/power/supply/gpio-charger.o
      CC [M]  drivers/power/supply/smb347-charger.o
      AR      drivers/power/supply/built-in.a
      AR      drivers/ptp/built-in.a
    sound/soc/codecs/tlv320aic326x.c:2628:19: error: initialization of 'int (*)(struct platform_device *)' from incompatible pointer type 'void (*)(struct platform_device *)' [-Werror=incompatible-pointer-types]
     2628 |         .remove = aic326x_remove,
          |                   ^~~~~~~~~~~~~~
    sound/soc/codecs/tlv320aic326x.c:2628:19: note: (near initialization for 'aic326x_codec_driver.remove')
    cc1: some warnings being treated as errors
    make[4]: *** [scripts/Makefile.build:250: sound/soc/codecs/tlv320aic326x.o] Error 1
    make[3]: *** [scripts/Makefile.build:505: sound/soc/codecs] Error 2
    make[2]: *** [scripts/Makefile.build:505: sound/soc] Error 2
    make[1]: *** [scripts/Makefile.build:505: sound] Error 2
    make[1]: *** Waiting for unfinished jobs....
      AR      drivers/power/built-in.a
    make[1]: *** [scripts/Makefile.build:505: drivers] Error 2
    make: *** [Makefile:2009: .] Error 2
    

    Could you please apply the patch on TI Linux SDK 9.03's kernel and share the patch upon successful compilation and probing  or resolve the errors above ? 

    I think the former approach would be better.

    I don't have the exact build setup which you have.

    You can install the SDK as root using the link below:-

    https://dr-download.ti.com/software-development/software-development-kit-sdk/MD-L1u0FxxpZf/09.03.06.05/ti-processor-sdk-linux-am57xx-evm-09_03_06_05-Linux-x86-Install.bin

    and apply patch in the directory below:-

    /opt/ti-processor-sdk-linux-am57xx-evm-09_03_06_05/board-support/ti-linux-kernel-6.1.119+gitAUTOINC+e4e8b16e66-ti

    Please resolve the issue! Thanks!

    -Vishal 

  • Sorry for the inconvenience, I think I forgot to downgrade the driver to 6.1 version. 

    Please try with this patch and let me know - this is prepared on the sdk kernel 

    From a0beff042494240e1500b8861739a2c0dff629a7 Mon Sep 17 00:00:00 2001
    From: Niranjan H Y <niranjan.hy@ti.com>
    Date: Thu, 4 Sep 2025 19:27:36 +0530
    Subject: [PATCH v3] Add driver for tlv320aic3262
    
    ---
     drivers/mfd/Kconfig                         |   31 +
     drivers/mfd/Makefile                        |    4 +
     drivers/mfd/tlv320aic3xxx-core.c            |  570 ++++
     drivers/mfd/tlv320aic3xxx-i2c.c             |  141 +
     drivers/mfd/tlv320aic3xxx-irq.c             |  222 ++
     drivers/mfd/tlv320aic3xxx-spi.c             |   91 +
     include/linux/mfd/tlv320aic3262-registers.h |  342 +++
     include/linux/mfd/tlv320aic3xxx-core.h      |  291 ++
     sound/soc/codecs/Kconfig                    |    8 +
     sound/soc/codecs/Makefile                   |    2 +
     sound/soc/codecs/aic3xxx/aic3xxx_cfw.h      |  529 ++++
     sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c  | 1134 ++++++++
     sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h  |   95 +
     sound/soc/codecs/tlv320aic326x.c            | 2641 +++++++++++++++++++
     sound/soc/codecs/tlv320aic326x.h            |  134 +
     15 files changed, 6235 insertions(+)
     create mode 100644 drivers/mfd/tlv320aic3xxx-core.c
     create mode 100644 drivers/mfd/tlv320aic3xxx-i2c.c
     create mode 100644 drivers/mfd/tlv320aic3xxx-irq.c
     create mode 100644 drivers/mfd/tlv320aic3xxx-spi.c
     create mode 100644 include/linux/mfd/tlv320aic3262-registers.h
     create mode 100644 include/linux/mfd/tlv320aic3xxx-core.h
     create mode 100644 sound/soc/codecs/aic3xxx/aic3xxx_cfw.h
     create mode 100644 sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c
     create mode 100644 sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h
     create mode 100644 sound/soc/codecs/tlv320aic326x.c
     create mode 100644 sound/soc/codecs/tlv320aic326x.h
    
    diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
    index 9f3b6cdf0..92620ec38 100644
    --- a/drivers/mfd/Kconfig
    +++ b/drivers/mfd/Kconfig
    @@ -1089,6 +1089,37 @@ config UCB1400_CORE
     	  To compile this driver as a module, choose M here: the
     	  module will be called ucb1400_core.
     
    +config AIC3XXX_I2C_REGMAP
    +	bool "I2C regmap support for TI AIC3XXX codecs"
    +	select REGMAP_I2C
    +	default y
    +	help
    +	  Support for the Texas Instruments TLV320AIC3XXX family of audio SoC
    +	  core functionality controlled via I2C.
    +	  Please select individual components.
    +
    +config AIC3XXX_SPI_REGMAP
    +	bool "SPI regmap support for TI AIC3XXX codecs"
    +	select REGMAP_SPI
    +	default n
    +	help
    +	  Support for the Texas Instruments TLV320AIC3XXX family of audio SoC
    +	  core functionality controlled via SPI.
    +	  Please select individual components.
    +
    +config AIC3XXX_CORE
    +	bool "Support for AIC3XXX audio codec"
    +	#depends on GENERIC_HARDIRQS
    +	select MFD_CORE
    +	select AIC3XXX_SPI_REGMAP
    +	select AIC3XXX_I2C_REGMAP
    +	default n
    +	help
    +	  Say yes here if you want support for Texas Instruments AIC3XXX audio
    +	  codec. This driver provides common support for accessing the device,
    +	  additional drivers must be enabled in order to use the
    +	  functionality of the device (audio, vibra).
    +
     config MFD_PM8XXX
     	tristate "Qualcomm PM8xxx PMIC chips driver"
     	depends on (ARM || HEXAGON || COMPILE_TEST)
    diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
    index 6bb56f3af..307a527dd 100644
    --- a/drivers/mfd/Makefile
    +++ b/drivers/mfd/Makefile
    @@ -34,6 +34,10 @@ obj-$(CONFIG_STMPE_I2C)		+= stmpe-i2c.o
     obj-$(CONFIG_STMPE_SPI)		+= stmpe-spi.o
     obj-$(CONFIG_MFD_SUN6I_PRCM)	+= sun6i-prcm.o
     obj-$(CONFIG_MFD_TC3589X)	+= tc3589x.o
    +
    +tlv320aic3xxx-objs := tlv320aic3xxx-core.o tlv320aic3xxx-irq.o tlv320aic3xxx-i2c.o
    +obj-$(CONFIG_AIC3XXX_CORE)	+= tlv320aic3xxx.o
    +
     obj-$(CONFIG_MFD_T7L66XB)	+= t7l66xb.o tmio_core.o
     obj-$(CONFIG_MFD_TC6387XB)	+= tc6387xb.o tmio_core.o
     obj-$(CONFIG_MFD_TC6393XB)	+= tc6393xb.o tmio_core.o
    diff --git a/drivers/mfd/tlv320aic3xxx-core.c b/drivers/mfd/tlv320aic3xxx-core.c
    new file mode 100644
    index 000000000..943825455
    --- /dev/null
    +++ b/drivers/mfd/tlv320aic3xxx-core.c
    @@ -0,0 +1,570 @@
    +/*
    + * tlv320aic3xxx-core.c  -- driver for TLV320AIC3XXX
    + *
    + * Author:      Mukund Navada <navada@ti.com>
    + *              Mehar Bajwa <mehar.bajwa@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +#include <linux/kernel.h>
    +#include <linux/module.h>
    +#include <linux/slab.h>
    +#include <linux/i2c.h>
    +#include <linux/err.h>
    +#include <linux/delay.h>
    +#include <linux/regmap.h>
    +#include <linux/mfd/core.h>
    +#include <linux/pm_runtime.h>
    +#include <linux/regulator/consumer.h>
    +#include <linux/regulator/machine.h>
    +#include <linux/gpio.h>
    +
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +#include <linux/mfd/tlv320aic3262-registers.h>
    +
    +struct aic3262_gpio {
    +	unsigned int reg;
    +	u8 mask;
    +	u8 shift;
    +};
    +struct aic3262_gpio aic3262_gpio_control[] = {
    +	{
    +	 .reg = AIC3262_GPIO1_IO_CNTL,
    +	 .mask = AIC3262_GPIO_D6_D2,
    +	 .shift = AIC3262_GPIO_D2_SHIFT,
    +	 },
    +	{
    +	 .reg = AIC3262_GPIO2_IO_CNTL,
    +	 .mask = AIC3262_GPIO_D6_D2,
    +	 .shift = AIC3262_GPIO_D2_SHIFT,
    +	 },
    +	{
    +	 .reg = AIC3262_GPI1_EN,
    +	 .mask = AIC3262_GPI1_D2_D1,
    +	 .shift = AIC3262_GPIO_D1_SHIFT,
    +	 },
    +	{
    +	 .reg = AIC3262_GPI2_EN,
    +	 .mask = AIC3262_GPI2_D5_D4,
    +	 .shift = AIC3262_GPIO_D4_SHIFT,
    +	 },
    +	{
    +	 .reg = AIC3262_GPO1_OUT_CNTL,
    +	 .mask = AIC3262_GPO1_D4_D1,
    +	 .shift = AIC3262_GPIO_D1_SHIFT,
    +	 },
    +};
    +
    +static int set_aic3xxx_book(struct aic3xxx *aic3xxx, int book)
    +{
    +	int ret = 0;
    +	u8 page_buf[] = { 0x0, 0x0 };
    +	u8 book_buf[] = { 0x7f, 0x0 };
    +
    +	ret = regmap_write(aic3xxx->regmap, page_buf[0], page_buf[1]);
    +
    +	if (ret < 0)
    +		return ret;
    +	book_buf[1] = book;
    +	ret = regmap_write(aic3xxx->regmap, book_buf[0], book_buf[1]);
    +
    +	if (ret < 0)
    +		return ret;
    +	aic3xxx->book_no = book;
    +	aic3xxx->page_no = 0;
    +
    +	return ret;
    +}
    +
    +static int set_aic3xxx_page(struct aic3xxx *aic3xxx, int page)
    +{
    +	int ret = 0;
    +	u8 page_buf[] = { 0x0, 0x0 };
    +
    +	page_buf[1] = page;
    +	ret = regmap_write(aic3xxx->regmap, page_buf[0], page_buf[1]);
    +
    +	if (ret < 0)
    +		return ret;
    +	aic3xxx->page_no = page;
    +	return ret;
    +}
    +/**
    + * aic3xxx_reg_read: Read a single TLV320AIC3262 register.
    + *
    + * @aic3xxx: Device to read from.
    + * @reg: Register to read.
    + */
    +int aic3xxx_reg_read(struct aic3xxx *aic3xxx, unsigned int reg)
    +{
    +	unsigned int val;
    +	int ret;
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	u8 book, page, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (aic3xxx->book_no != book) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +
    +	if (aic3xxx->page_no != page) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_read(aic3xxx->regmap, offset, &val);
    +	mutex_unlock(&aic3xxx->io_lock);
    +
    +	if (ret < 0)
    +		return ret;
    +	else
    +		return val;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_reg_read);
    +
    +/**
    + * aic3xxx_bulk_read: Read multiple TLV320AIC3262 registers
    + *
    + * @aic3xxx: Device to read from
    + * @reg: First register
    + * @count: Number of registers
    + * @buf: Buffer to fill.  The data will be returned big endian.
    + */
    +int aic3xxx_bulk_read(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      int count, u8 *buf)
    +{
    +	int ret;
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	u8 book, page, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (aic3xxx->book_no != book) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +
    +	if (aic3xxx->page_no != page) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_bulk_read(aic3xxx->regmap, offset, buf, count);
    +	mutex_unlock(&aic3xxx->io_lock);
    +		return ret;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_bulk_read);
    +
    +/**
    + * aic3xxx_reg_write: Write a single TLV320AIC3262 register.
    + *
    + * @aic3xxx: Device to write to.
    + * @reg: Register to write to.
    + * @val: Value to write.
    + */
    +int aic3xxx_reg_write(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      unsigned char val)
    +{
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	int ret = 0;
    +	u8 page, book, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (book != aic3xxx->book_no) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	if (page != aic3xxx->page_no) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_write(aic3xxx->regmap, reg, val);
    +	mutex_unlock(&aic3xxx->io_lock);
    +	return ret;
    +
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_reg_write);
    +
    +/**
    + * aic3xxx_bulk_write: Write multiple TLV320AIC3262 registers
    + *
    + * @aic3xxx: Device to write to
    + * @reg: First register
    + * @count: Number of registers
    + * @buf: Buffer to write from.  Data must be big-endian formatted.
    + */
    +int aic3xxx_bulk_write(struct aic3xxx *aic3xxx, unsigned int reg,
    +		       int count, const u8 *buf)
    +{
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	int ret = 0;
    +	u8 page, book, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (book != aic3xxx->book_no) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	if (page != aic3xxx->page_no) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_raw_write(aic3xxx->regmap, reg, buf, count);
    +	mutex_unlock(&aic3xxx->io_lock);
    +	return ret;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_bulk_write);
    +
    +/**
    + * aic3xxx_set_bits: Set the value of a bitfield in a TLV320AIC3262 register
    + *
    + * @aic3xxx: Device to write to.
    + * @reg: Register to write to.
    + * @mask: Mask of bits to set.
    + * @val: Value to set (unshifted)
    + */
    +int aic3xxx_set_bits(struct aic3xxx *aic3xxx, unsigned int reg,
    +		     unsigned char mask, unsigned char val)
    +{
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	int ret = 0;
    +	u8 page, book, offset;
    +
    +	page = aic_reg->aic3xxx_register.page;
    +	book = aic_reg->aic3xxx_register.book;
    +	offset = aic_reg->aic3xxx_register.offset;
    +
    +	mutex_lock(&aic3xxx->io_lock);
    +	if (book != aic3xxx->book_no) {
    +		ret = set_aic3xxx_book(aic3xxx, book);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	if (page != aic3xxx->page_no) {
    +		ret = set_aic3xxx_page(aic3xxx, page);
    +		if (ret < 0) {
    +			mutex_unlock(&aic3xxx->io_lock);
    +			return ret;
    +		}
    +	}
    +	ret = regmap_update_bits(aic3xxx->regmap, offset, mask, val);
    +	mutex_unlock(&aic3xxx->io_lock);
    +	return ret;
    +
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_set_bits);
    +
    +/**
    + * aic3xxx_wait_bits: wait for a value of a bitfield in a TLV320AIC3262 register
    + *
    + * @aic3xxx: Device to write to.
    + * @reg: Register to write to.
    + * @mask: Mask of bits to set.
    + * @val: Value to set (unshifted)
    + * @mdelay: mdelay value in each iteration in milliseconds
    + * @count: iteration count for timeout
    + */
    +int aic3xxx_wait_bits(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      unsigned char mask, unsigned char val, int sleep,
    +		      int counter)
    +{
    +	int status;
    +	int timeout = sleep * counter;
    +
    +	status = aic3xxx_reg_read(aic3xxx, reg);
    +	while (((status & mask) != val) && counter) {
    +		mdelay(sleep);
    +		status = aic3xxx_reg_read(aic3xxx, reg);
    +		counter--;
    +	};
    +	if (!counter)
    +		dev_err(aic3xxx->dev,
    +			"wait_bits timedout (%d millisecs). lastval 0x%x\n",
    +			timeout, status);
    +	return counter;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_wait_bits);
    +
    +static struct mfd_cell aic3262_devs[] = {
    +	{
    +	.name = "tlv320aic3262-codec",
    +	},
    +	//{
    +	//.name = "tlv320aic3262-gpio",
    +	//},
    +};
    +
    +static struct mfd_cell aic3285_devs[] = {
    +	{ .name = "tlv320aic3285-codec" },
    +	{ .name = "tlv320aic3285-extcon" },
    +	{ .name = "tlv320aic3285-gpio" },
    +};
    +
    +static int aic3xxx_parse_pdata_from_of(struct aic3xxx *aic3xxx)
    +{
    +	u32 gpio_reset;
    +	s32 ret;
    +	struct device *dev = aic3xxx->dev;
    +	struct aic3xxx_pdata *pdata = aic3xxx->pdata;
    +	struct device_node *np = dev->of_node;
    +
    +	pdata->gpio_reset = 0;
    +	/* disable interrupts */
    +	pdata->naudint_irq = 0;
    +	pdata->gpio_irq = 0;
    +	pdata->irq_base = 0;
    +
    +	if (np) {
    +		ret = of_property_read_u32(np, "ti,reset-gpio", &gpio_reset);
    +		if (ret)
    +			dev_err(aic3xxx->dev, "Unable to read reset-gpio property\n");
    +	} else {
    +		dev_info(dev, "No device tree node\n");
    +	}
    +
    +	return 0;
    +}
    +
    +/**
    + * Instantiate the generic non-control parts of the device.
    + */
    +int aic3xxx_device_init(struct aic3xxx *aic3xxx, int irq)
    +{
    +	struct aic3xxx_pdata *pdata; // = aic3xxx->dev->platform_data;
    +	const char *devname;
    +	int ret, i;
    +	u8 resetVal = 1;
    +
    +	dev_info(aic3xxx->dev, "aic3xxx_device_init beginning\n");
    +
    +	mutex_init(&aic3xxx->io_lock);
    +	dev_set_drvdata(aic3xxx->dev, aic3xxx);
    +
    +	pdata = devm_kzalloc(aic3xxx->dev, sizeof(*pdata), GFP_KERNEL);
    +	if (!pdata)
    +		return -ENOMEM;
    +
    +	aic3xxx->pdata = pdata;
    +	ret = aic3xxx_parse_pdata_from_of(aic3xxx);
    +	if (ret) {
    +		dev_err(aic3xxx->dev, "platform data parse failed");
    +		goto err_return;
    +	}
    +
    +	/*GPIO reset for TLV320AIC3262 codec */
    +	if (pdata->gpio_reset) {
    +		ret = gpio_request(pdata->gpio_reset, "aic3xxx-reset-pin");
    +		if (ret != 0) {
    +			dev_err(aic3xxx->dev, "not able to acquire gpio\n");
    +			goto err_return;
    +		}
    +		gpio_direction_output(pdata->gpio_reset, 1);
    +		mdelay(5);
    +		gpio_direction_output(pdata->gpio_reset, 0);
    +		mdelay(5);
    +		gpio_direction_output(pdata->gpio_reset, 1);
    +		mdelay(5);
    +	}
    +
    +	/* run the codec through software reset */
    +	ret = aic3xxx_reg_write(aic3xxx, AIC3262_RESET_REG, resetVal);
    +	if (ret < 0) {
    +		dev_err(aic3xxx->dev, "Could not write to AIC3262 register\n");
    +		goto err_return;
    +	}
    +
    +	mdelay(10);
    +
    +	ret = aic3xxx_reg_read(aic3xxx, AIC3262_DEVICE_ID);
    +	if (ret < 0) {
    +		dev_err(aic3xxx->dev, "Failed to read ID register\n");
    +		goto err_return;
    +	}
    +
    +	//TODO: //remove this
    +	ret = 3;
    +
    +	switch (ret) {
    +	case 3:
    +		devname = "TLV320AIC3262";
    +		if (aic3xxx->type != TLV320AIC3262)
    +			dev_warn(aic3xxx->dev, "Device registered as type %d\n",
    +				 aic3xxx->type);
    +		aic3xxx->type = TLV320AIC3262;
    +		break;
    +	case 4:
    +		devname = "TLV320AIC3285";
    +		if (aic3xxx->type != TLV320AIC3285)
    +			dev_warn(aic3xxx->dev, "Device registered as type %d\n",
    +				 aic3xxx->type);
    +		aic3xxx->type = TLV320AIC3285;
    +	fallthrough;
    +	default:
    +		dev_err(aic3xxx->dev, "Device is not a TLV320AIC3262");
    +		ret = -EINVAL;
    +		goto err_return;
    +	}
    +
    +	dev_info(aic3xxx->dev, "%s revision %c\n", devname, 'D' + ret);
    +
    +	/*If naudint is gpio convert it to irq number */
    +	if (pdata->gpio_irq == 1) {
    +		aic3xxx->irq = gpio_to_irq(pdata->naudint_irq);
    +		gpio_request(pdata->naudint_irq, "aic3xxx-gpio-irq");
    +		gpio_direction_input(pdata->naudint_irq);
    +	} else
    +		aic3xxx->irq = pdata->naudint_irq;
    +
    +	aic3xxx->irq_base = pdata->irq_base;
    +	for (i = 0; i < AIC3262_NUM_GPIO; i++) {
    +		if (pdata->gpio && pdata->gpio[i].used) {
    +			if (pdata->gpio[i].in) {
    +				aic3xxx_set_bits(aic3xxx,
    +						 aic3262_gpio_control[i].reg,
    +						 aic3262_gpio_control[i].mask,
    +						 0x1 << aic3262_gpio_control[i].
    +						 shift);
    +				if (pdata->gpio[i].in_reg)
    +					aic3xxx_set_bits(aic3xxx,
    +							 pdata->gpio[i].in_reg,
    +							 pdata->gpio[i].
    +							 in_reg_bitmask,
    +							 pdata->gpio[i].
    +							 value << pdata->
    +							 gpio[i].in_reg_shift);
    +			} else {
    +				aic3xxx_set_bits(aic3xxx,
    +						 aic3262_gpio_control[i].reg,
    +						 aic3262_gpio_control[i].mask,
    +						 pdata->gpio[i].
    +						 value <<
    +						 aic3262_gpio_control[i].shift);
    +			}
    +		} else
    +			aic3xxx_set_bits(aic3xxx, aic3262_gpio_control[i].reg,
    +					 aic3262_gpio_control[i].mask, 0x0);
    +	}
    +
    +	/* codec interrupt */
    +	if (aic3xxx->irq) {
    +		ret = aic3xxx_irq_init(aic3xxx);
    +		if (ret < 0)
    +			goto err_irq;
    +	}
    +	switch (aic3xxx->type) {
    +	case TLV320AIC3262:
    +		dev_info(aic3xxx->dev, "adding codec device");
    +		ret = mfd_add_devices(aic3xxx->dev, -1,
    +			      aic3262_devs, ARRAY_SIZE(aic3262_devs), NULL, 0, NULL);
    +		break;
    +
    +	case TLV320AIC3285:
    +		ret = mfd_add_devices(aic3xxx->dev, -1,
    +			      aic3285_devs, ARRAY_SIZE(aic3285_devs), NULL, 0, NULL);
    +		break;
    +	case TLV320AIC3266:
    +		break;
    +
    +	default:
    +		dev_err(aic3xxx->dev, "unable to recognize codec\n");
    +	}
    +	if (ret != 0) {
    +		dev_err(aic3xxx->dev, "Failed to add children: %d\n", ret);
    +		goto err_mfd;
    +	}
    +	dev_info(aic3xxx->dev, "aic3xxx_device_init added mfd devices\n");
    +
    +	pm_runtime_enable(aic3xxx->dev);
    +	pm_runtime_resume(aic3xxx->dev);
    +
    +	return 0;
    +
    +err_mfd:
    +
    +	aic3xxx_irq_exit(aic3xxx);
    +err_irq:
    +
    +	if (pdata && pdata->gpio_irq)
    +		gpio_free(pdata->naudint_irq);
    +err_return:
    +
    +	if (pdata && pdata->gpio_reset)
    +		gpio_free(pdata->gpio_reset);
    +
    +	return ret;
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_device_init);
    +
    +void aic3xxx_device_exit(struct aic3xxx *aic3xxx)
    +{
    +	struct aic3xxx_pdata *pdata = aic3xxx->dev->platform_data;
    +
    +	pm_runtime_disable(aic3xxx->dev);
    +	mfd_remove_devices(aic3xxx->dev);
    +	aic3xxx_irq_exit(aic3xxx);
    +
    +	if (pdata && pdata->gpio_irq)
    +		gpio_free(pdata->naudint_irq);
    +	if (pdata && pdata->gpio_reset)
    +		gpio_free(pdata->gpio_reset);
    +
    +}
    +EXPORT_SYMBOL_GPL(aic3xxx_device_exit);
    +
    +MODULE_AUTHOR("Mukund Navada <navada@ti.comm>");
    +MODULE_AUTHOR("Mehar Bajwa <mehar.bajwa@ti.com>");
    +MODULE_DESCRIPTION("Core support for the TLV320AIC3XXX audio CODEC");
    +MODULE_LICENSE("GPL");
    diff --git a/drivers/mfd/tlv320aic3xxx-i2c.c b/drivers/mfd/tlv320aic3xxx-i2c.c
    new file mode 100644
    index 000000000..c84238632
    --- /dev/null
    +++ b/drivers/mfd/tlv320aic3xxx-i2c.c
    @@ -0,0 +1,141 @@
    +/*
    + * tlv320aic3xxx-i2c.c  -- driver for TLV320AIC3XXX TODO
    + *
    + * Author:	Mukund Navada <navada@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#include <linux/kernel.h>
    +#include <linux/err.h>
    +#include <linux/i2c.h>
    +#include <linux/module.h>
    +#include <linux/pm_runtime.h>
    +#include <linux/regmap.h>
    +#include <linux/regulator/consumer.h>
    +#include <linux/slab.h>
    +
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +
    +struct regmap_config aicxxx_i2c_regmap = {
    +	.reg_bits = 8,
    +	.val_bits = 8,
    +	.cache_type = REGCACHE_NONE,
    +};
    +
    +#ifdef CONFIG_PM
    +static int aic3xxx_suspend(struct device *dev)
    +{
    +	struct aic3xxx *aic3xxx = dev_get_drvdata(dev);
    +
    +	aic3xxx->suspended = true;
    +
    +	return 0;
    +}
    +
    +static int aic3xxx_resume(struct device *dev)
    +{
    +	struct aic3xxx *aic3xxx = dev_get_drvdata(dev);
    +
    +	aic3xxx->suspended = false;
    +
    +	return 0;
    +}
    +#endif
    +
    +static int aic3xxx_i2c_probe(struct i2c_client *i2c,
    +					  const struct i2c_device_id *id)
    +{
    +	struct aic3xxx *aicxxx;
    +	const struct regmap_config *regmap_config;
    +	int ret;
    +
    +	switch (id->driver_data) {
    +	case TLV320AIC3262:
    +	case TLV320AIC3268:
    +		regmap_config = &aicxxx_i2c_regmap;
    +		break;
    +	case TLV320AIC3285:
    +		regmap_config = &aicxxx_i2c_regmap;
    +		break;
    +	default:
    +		dev_err(&i2c->dev, "Unknown device type %ld\n",
    +			id->driver_data);
    +		return -EINVAL;
    +	}
    +
    +	aicxxx = devm_kzalloc(&i2c->dev, sizeof(*aicxxx), GFP_KERNEL);
    +	if (aicxxx == NULL)
    +		return -ENOMEM;
    +
    +	aicxxx->regmap = devm_regmap_init_i2c(i2c, regmap_config);
    +
    +	if (IS_ERR(aicxxx->regmap)) {
    +		ret = PTR_ERR(aicxxx->regmap);
    +		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
    +			ret);
    +		return ret;
    +	}
    +
    +	aicxxx->type = id->driver_data;
    +	aicxxx->dev = &i2c->dev;
    +	aicxxx->irq = i2c->irq;
    +
    +	return aic3xxx_device_init(aicxxx, aicxxx->irq);
    +}
    +
    +static void aic3xxx_i2c_remove(struct i2c_client *i2c)
    +{
    +	struct aic3xxx *aicxxx = dev_get_drvdata(&i2c->dev);
    +	aic3xxx_device_exit(aicxxx);
    +	//return 0;
    +}
    +
    +static const struct of_device_id tlv320aic326X_of_match[] = {
    +	{ .compatible = "ti,tlv320aic3262", .data = (void *)TLV320AIC3262 },
    +	{ .compatible = "ti,tlv320aic3268", .data = (void *)TLV320AIC3268 },
    +	{ .compatible = "ti,tlv320aic3285", .data = (void *)TLV320AIC3285 },
    +	{ },
    +};
    +
    +static const struct i2c_device_id aic3xxx_i2c_id[] = {
    +	{"tlv320aic3262", TLV320AIC3262},
    +	{"tlv320aic3268", TLV320AIC3268},
    +	{"tlv320aic3285", TLV320AIC3285},
    +	{ }
    +};
    +MODULE_DEVICE_TABLE(i2c, aic3xxx_i2c_id);
    +
    +static UNIVERSAL_DEV_PM_OPS(aic3xxx_pm_ops, aic3xxx_suspend, aic3xxx_resume,
    +				NULL);
    +
    +static struct i2c_driver aic3xxx_i2c_driver = {
    +	.driver = {
    +		.name	= "tlv320aic3xxx",
    +		.owner	= THIS_MODULE,
    +		.pm	= &aic3xxx_pm_ops,
    +		.of_match_table = of_match_ptr(tlv320aic326X_of_match),
    +	},
    +	.probe		= aic3xxx_i2c_probe,
    +	.remove		= aic3xxx_i2c_remove,
    +	.id_table	= aic3xxx_i2c_id,
    +};
    +
    +module_i2c_driver(aic3xxx_i2c_driver);
    +
    +MODULE_DESCRIPTION("TLV320AIC3XXX I2C bus interface");
    +MODULE_AUTHOR("Mukund Navada <navada@ti.com>");
    +MODULE_LICENSE("GPL");
    diff --git a/drivers/mfd/tlv320aic3xxx-irq.c b/drivers/mfd/tlv320aic3xxx-irq.c
    new file mode 100644
    index 000000000..0729ad5db
    --- /dev/null
    +++ b/drivers/mfd/tlv320aic3xxx-irq.c
    @@ -0,0 +1,222 @@
    +/*
    + * tlv320aic3262-irq.c  --  Interrupt controller support for
    + *			 TI OMAP44XX TLV320AIC3262
    + *
    + * Author:      Mukund Navada <navada@ti.com>
    + *              Mehar Bajwa <mehar.bajwa@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#include <linux/kernel.h>
    +#include <linux/module.h>
    +#include <linux/i2c.h>
    +#include <linux/irq.h>
    +#include <linux/mfd/core.h>
    +#include <linux/interrupt.h>
    +
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +#include <linux/mfd/tlv320aic3262-registers.h>
    +
    +#include <linux/delay.h>
    +
    +struct aic3262_irq_data {
    +	int mask;
    +	int status;
    +};
    +
    +static struct aic3262_irq_data aic3262_irqs[] = {
    +	{
    +	 .mask = AIC3262_HEADSET_IN_MASK,
    +	 .status = AIC3262_HEADSET_PLUG_UNPLUG_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_BUTTON_PRESS_MASK,
    +	 .status = AIC3262_BUTTON_PRESS_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_DAC_DRC_THRES_MASK,
    +	 .status = AIC3262_LEFT_DRC_THRES_INT | AIC3262_RIGHT_DRC_THRES_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_AGC_NOISE_MASK,
    +	 .status = AIC3262_LEFT_AGC_NOISE_INT | AIC3262_RIGHT_AGC_NOISE_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_OVER_CURRENT_MASK,
    +	 .status = AIC3262_LEFT_OUTPUT_DRIVER_OVERCURRENT_INT
    +	 | AIC3262_RIGHT_OUTPUT_DRIVER_OVERCURRENT_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_OVERFLOW_MASK,
    +	 .status =
    +	 AIC3262_LEFT_DAC_OVERFLOW_INT | AIC3262_RIGHT_DAC_OVERFLOW_INT |
    +	 AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT |
    +	 AIC3262_LEFT_ADC_OVERFLOW_INT | AIC3262_RIGHT_ADC_OVERFLOW_INT |
    +	 AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT,
    +	 },
    +	{
    +	 .mask = AIC3262_SPK_OVERCURRENT_MASK,
    +	 .status = AIC3262_SPK_OVER_CURRENT_INT,
    +	 },
    +
    +};
    +
    +struct aic3262_gpio_data {
    +
    +};
    +
    +static inline struct aic3262_irq_data *irq_to_aic3262_irq(struct aic3xxx
    +							  *aic3262, int irq)
    +{
    +	return &aic3262_irqs[irq - aic3262->irq_base];
    +}
    +
    +static void aic3262_irq_lock(struct irq_data *data)
    +{
    +	struct aic3xxx *aic3262 = irq_data_get_irq_chip_data(data);
    +
    +	mutex_lock(&aic3262->irq_lock);
    +}
    +
    +static void aic3262_irq_sync_unlock(struct irq_data *data)
    +{
    +	struct aic3xxx *aic3262 = irq_data_get_irq_chip_data(data);
    +
    +	/* write back to hardware any change in irq mask */
    +	if (aic3262->irq_masks_cur != aic3262->irq_masks_cache) {
    +		aic3262->irq_masks_cache = aic3262->irq_masks_cur;
    +		aic3xxx_reg_write(aic3262, AIC3262_INT1_CNTL,
    +				  aic3262->irq_masks_cur);
    +	}
    +
    +	mutex_unlock(&aic3262->irq_lock);
    +}
    +
    +static void aic3262_irq_unmask(struct irq_data *data)
    +{
    +	struct aic3xxx *aic3262 = irq_data_get_irq_chip_data(data);
    +	struct aic3262_irq_data *irq_data =
    +	    irq_to_aic3262_irq(aic3262, data->irq);
    +
    +	aic3262->irq_masks_cur |= irq_data->mask;
    +}
    +
    +static void aic3262_irq_mask(struct irq_data *data)
    +{
    +	struct aic3xxx *aic3262 = irq_data_get_irq_chip_data(data);
    +	struct aic3262_irq_data *irq_data =
    +	    irq_to_aic3262_irq(aic3262, data->irq);
    +
    +	aic3262->irq_masks_cur &= ~irq_data->mask;
    +}
    +
    +static struct irq_chip aic3262_irq_chip = {
    +	.name = "tlv320aic3262",
    +	.irq_bus_lock = aic3262_irq_lock,
    +	.irq_bus_sync_unlock = aic3262_irq_sync_unlock,
    +	.irq_mask = aic3262_irq_mask,
    +	.irq_unmask = aic3262_irq_unmask,
    +};
    +
    +static irqreturn_t aic3262_irq_thread(int irq, void *data)
    +{
    +	struct aic3xxx *aic3262 = data;
    +	u8 status[4];
    +
    +	/* Reading sticky bit registers acknowledges
    +		the interrupt to the device */
    +	aic3xxx_bulk_read(aic3262, AIC3262_INT_STICKY_FLAG1, 4, status);
    +
    +	/* report  */
    +	if (status[2] & aic3262_irqs[AIC3262_IRQ_HEADSET_DETECT].status)
    +		handle_nested_irq(aic3262->irq_base);
    +	if (status[2] & aic3262_irqs[AIC3262_IRQ_BUTTON_PRESS].status)
    +		handle_nested_irq(aic3262->irq_base + 1);
    +	if (status[2] & aic3262_irqs[AIC3262_IRQ_DAC_DRC].status)
    +		handle_nested_irq(aic3262->irq_base + 2);
    +	if (status[3] & aic3262_irqs[AIC3262_IRQ_AGC_NOISE].status)
    +		handle_nested_irq(aic3262->irq_base + 3);
    +	if (status[2] & aic3262_irqs[AIC3262_IRQ_OVER_CURRENT].status)
    +		handle_nested_irq(aic3262->irq_base + 4);
    +	if (status[0] & aic3262_irqs[AIC3262_IRQ_OVERFLOW_EVENT].status)
    +		handle_nested_irq(aic3262->irq_base + 5);
    +	if (status[3] & aic3262_irqs[AIC3262_IRQ_SPEAKER_OVER_TEMP].status)
    +		handle_nested_irq(aic3262->irq_base + 6);
    +
    +	/* ack unmasked irqs */
    +	/* No need to acknowledge the interrupt on AIC3262 */
    +
    +	return IRQ_HANDLED;
    +}
    +
    +int aic3xxx_irq_init(struct aic3xxx *aic3262)
    +{
    +	int cur_irq, ret;
    +
    +	mutex_init(&aic3262->irq_lock);
    +
    +	/* mask the individual interrupt sources */
    +	aic3262->irq_masks_cur = 0x0;
    +	aic3262->irq_masks_cache = 0x0;
    +	aic3xxx_reg_write(aic3262, AIC3262_INT1_CNTL, 0x0);
    +
    +	if (!aic3262->irq) {
    +		dev_warn(aic3262->dev,
    +			 "no interrupt specified, no interrupts\n");
    +		aic3262->irq_base = 0;
    +		return 0;
    +	}
    +
    +	if (!aic3262->irq_base) {
    +		dev_err(aic3262->dev,
    +			"no interrupt base specified, no interrupts\n");
    +		return 0;
    +	}
    +
    +	/* Register them with genirq */
    +	for (cur_irq = aic3262->irq_base;
    +	     cur_irq < aic3262->irq_base + ARRAY_SIZE(aic3262_irqs);
    +	     cur_irq++) {
    +		irq_set_chip_data(cur_irq, aic3262);
    +		irq_set_chip_and_handler(cur_irq, &aic3262_irq_chip,
    +					 handle_edge_irq);
    +		irq_set_nested_thread(cur_irq, 1);
    +	}
    +	ret = request_threaded_irq(aic3262->irq, NULL, aic3262_irq_thread,
    +				   IRQF_TRIGGER_RISING,
    +				   "tlv320aic3262", aic3262);
    +	if (ret < 0) {
    +		dev_err(aic3262->dev, "failed to request IRQ %d: %d\n",
    +			aic3262->irq, ret);
    +		return ret;
    +	}
    +
    +	return 0;
    +}
    +EXPORT_SYMBOL(aic3xxx_irq_init);
    +
    +void aic3xxx_irq_exit(struct aic3xxx *aic3262)
    +{
    +	if (aic3262->irq)
    +		free_irq(aic3262->irq, aic3262);
    +}
    +EXPORT_SYMBOL(aic3xxx_irq_exit);
    +MODULE_AUTHOR("Mukund navada <navada@ti.com>");
    +MODULE_AUTHOR("Mehar Bajwa <mehar.bajwa@ti.com>");
    +MODULE_DESCRIPTION
    +	("Interrupt controller support for TI OMAP44XX TLV320AIC3262");
    +MODULE_LICENSE("GPL");
    diff --git a/drivers/mfd/tlv320aic3xxx-spi.c b/drivers/mfd/tlv320aic3xxx-spi.c
    new file mode 100644
    index 000000000..a148bc603
    --- /dev/null
    +++ b/drivers/mfd/tlv320aic3xxx-spi.c
    @@ -0,0 +1,91 @@
    +
    +#include <linux/err.h>
    +#include <linux/module.h>
    +#include <linux/pm_runtime.h>
    +#include <linux/regmap.h>
    +#include <linux/regulator/consumer.h>
    +#include <linux/slab.h>
    +#include <linux/spi/spi.h>
    +
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +
    +struct regmap_config tlv320aic3xxx_spi_regmap = {
    +	.reg_bits = 8,
    +	.val_bits = 8,
    +	.cache_type = REGCACHE_NONE,
    +	.read_flag_mask = 0x1,
    +};
    +
    +static int tlv320aic3xxx_spi_probe(struct spi_device *spi)
    +{
    +	const struct spi_device_id *id = spi_get_device_id(spi);
    +	struct aic3xxx *tlv320aic3xxx;
    +	const struct regmap_config *regmap_config;
    +	int ret;
    +
    +	switch (id->driver_data) {
    +#ifdef CONFIG_SND_SOC_AIC3262
    +	case TLV320AIC3262:
    +		regmap_config = &tlv320aic3xxx_spi_regmap;
    +		break;
    +#endif
    +#ifdef CONFIG_MFD_AIC3285
    +	case TLV320AIC3285:
    +		regmap_config = &tlv320aic3285_spi_regmap;
    +		break;
    +#endif
    +	default:
    +		dev_err(&spi->dev, "Unknown device type %ld\n",
    +			id->driver_data);
    +		return -EINVAL;
    +	}
    +
    +	tlv320aic3xxx = devm_kzalloc(&spi->dev, sizeof(struct aic3xxx),
    +				    GFP_KERNEL);
    +	if (tlv320aic3xxx == NULL)
    +		return -ENOMEM;
    +
    +	tlv320aic3xxx->regmap = devm_regmap_init_spi(spi, regmap_config);
    +	if (IS_ERR(tlv320aic3xxx->regmap)) {
    +		ret = PTR_ERR(tlv320aic3xxx->regmap);
    +		dev_err(&spi->dev, "Failed to allocate register map: %d\n",
    +			ret);
    +		return ret;
    +	}
    +
    +	tlv320aic3xxx->type = id->driver_data;
    +	tlv320aic3xxx->dev = &spi->dev;
    +	tlv320aic3xxx->irq = spi->irq;
    +
    +	return aic3xxx_device_init(tlv320aic3xxx, tlv320aic3xxx->irq);
    +}
    +
    +static int tlv320aic3xxx_spi_remove(struct spi_device *spi)
    +{
    +	struct aic3xxx *tlv320aic3xxx = dev_get_drvdata(&spi->dev);
    +	aic3xxx_device_exit(tlv320aic3xxx);
    +	return 0;
    +}
    +
    +static const struct spi_device_id aic3xxx_spi_ids[] = {
    +	{"tlv320aic3262", TLV320AIC3262},
    +	{"tlv320aic3285", TLV320AIC3285},
    +	{ }
    +};
    +MODULE_DEVICE_TABLE(spi, aic3xxx_spi_ids);
    +
    +static struct spi_driver tlv320aic3xxx_spi_driver = {
    +	.driver = {
    +		.name	= "tlv320aic3xxx",
    +		.owner	= THIS_MODULE,
    +	},
    +	.probe		= tlv320aic3xxx_spi_probe,
    +	.remove		= tlv320aic3xxx_spi_remove,
    +	.id_table	= aic3xxx_spi_ids,
    +};
    +
    +module_spi_driver(tlv320aic3xxx_spi_driver);
    +
    +MODULE_DESCRIPTION("TLV320AIC3XXX SPI bus interface");
    +MODULE_AUTHOR("Mukund Navada <navada@ti.com>");
    +MODULE_LICENSE("GPL");
    diff --git a/include/linux/mfd/tlv320aic3262-registers.h b/include/linux/mfd/tlv320aic3262-registers.h
    new file mode 100644
    index 000000000..7b91ee574
    --- /dev/null
    +++ b/include/linux/mfd/tlv320aic3262-registers.h
    @@ -0,0 +1,342 @@
    +
    +/*
    + *tlv320aic3262-registers: Register bits for AIC3262 codecs
    + *
    + *
    + * Author:      Mukund Navada <navada@ti.com>
    + *              Mehar Bajwa <mehar.bajwa@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#ifndef __MFD_AIC3262_REGISTERS_H__
    +#define __MFD_AIC3262_REGISTERS_H__
    +
    +#define MAKE_REG(book, page, offset) \
    +	(unsigned int)((book << 16)|(page << 8)|offset)
    +
    +/* ****************** Book 0 Registers **************************************/
    +
    +/* ****************** Page 0 Registers **************************************/
    +#define AIC3262_PAGE_SEL_REG		MAKE_REG(0, 0, 0)
    +#define AIC3262_RESET_REG		MAKE_REG(0, 0, 1)
    +#define AIC3262_REV_PG_ID		MAKE_REG(0, 0, 2)
    +#define AIC3262_REV_MASK		(0b01110000)
    +#define AIC3262_REV_SHIFT		4
    +#define AIC3262_PG_MASK			(0b00000111)
    +#define AIC3262_PG_SHIFT		0
    +#define AIC3262_DAC_ADC_CLKIN_REG	MAKE_REG(0, 0, 4)
    +#define AIC3262_PLL_CLKIN_REG		MAKE_REG(0, 0, 5)
    +#define AIC3262_PLL_CLKIN_MASK		(0b00111100)
    +#define AIC3262_PLL_CLKIN_SHIFT		2
    +#define AIC3262_PLL_CLKIN_MCLK1		0
    +#define AIC3262_PLL_CLKIN_BCLK1		1
    +#define AIC3262_PLL_CLKIN_GPIO1		2
    +#define AIC3262_PLL_CLKIN_DIN1		3
    +#define AIC3262_PLL_CLKIN_BCLK2		4
    +#define AIC3262_PLL_CLKIN_GPI1		5
    +#define AIC3262_PLL_CLKIN_HF_REF_CLK	6
    +#define AIC3262_PLL_CLKIN_GPIO2		7
    +#define AIC3262_PLL_CLKIN_GPI2		8
    +#define AIC3262_PLL_CLKIN_MCLK2		9
    +#define AIC3262_CLK_VAL_MASK		0x7f
    +#define AIC3262_PLL_CLK_RANGE_REG	MAKE_REG(0, 0, 5)
    +#define AIC3262_PLL_PR_POW_REG		MAKE_REG(0, 0, 6)
    +#define AIC3262_PLL_PVAL_MASK		0x70
    +#define AIC3262_PLL_RVAL_MASK		0x0F
    +
    +#define AIC3262_ENABLE_CLK_MASK		0x80
    +#define AIC3262_ENABLE_CLK		0x80
    +
    +#define AIC3262_PLL_J_REG		MAKE_REG(0, 0, 7)
    +#define AIC3262_JVAL_MASK		0x3f
    +#define AIC3262_PLL_D_MSB		MAKE_REG(0, 0, 8)
    +#define AIC3262_DVAL_MSB_MASK		0xf
    +#define AIC3262_DVAL_LSB_MASK		0xff
    +#define AIC3262_PLL_D_LSB		MAKE_REG(0, 0, 9)
    +#define AIC3262_PLL_CKIN_DIV		MAKE_REG(0, 0, 10)
    +
    +#define AIC3262_NDAC_DIV_POW_REG	MAKE_REG(0, 0, 11)
    +#define AIC3262_MDAC_DIV_POW_REG	MAKE_REG(0, 0, 12)
    +#define AIC3262_DOSR_MSB_REG		MAKE_REG(0, 0, 13)
    +#define AIC3262_DOSR_MSB_MASK		0x3
    +#define AIC3262_DOSR_LSB_REG		MAKE_REG(0, 0, 14)
    +#define AIC3262_DOSR_LSB_MASK		0xFF
    +
    +#define AIC3262_NADC_DIV_POW_REG	MAKE_REG(0, 0, 18)
    +#define AIC3262_MADC_DIV_POW_REG	MAKE_REG(0, 0, 19)
    +#define AIC3262_AOSR_REG		MAKE_REG(0, 0, 20)
    +#define AIC3262_CLKOUT_MUX		MAKE_REG(0, 0, 21)
    +#define AIC3262_CLKOUT_MDIV_VAL		MAKE_REG(0, 0, 22)
    +#define AIC3262_TIMER_REG		MAKE_REG(0, 0, 23)
    +
    +#define AIC3262_LF_CLK_CNTL		MAKE_REG(0, 0, 24)
    +#define AIC3262_HF_CLK_CNTL_R1		MAKE_REG(0, 0, 25)
    +#define AIC3262_HF_CLK_CNTL_R2		MAKE_REG(0, 0, 26)
    +#define AIC3262_HF_CLK_CNTL_R3		MAKE_REG(0, 0, 27)
    +#define AIC3262_HF_CLK_CNTL_R4		MAKE_REG(0, 0, 28)
    +#define AIC3262_HF_CLK_TRIM_R1		MAKE_REG(0, 0, 29)
    +#define AIC3262_HF_CLK_TRIM_R2		MAKE_REG(0, 0, 30)
    +#define AIC3262_HF_CLK_TRIM_R3		MAKE_REG(0, 0, 31)
    +#define AIC3262_HF_CLK_TRIM_R4		MAKE_REG(0, 0, 32)
    +#define AIC3262_LDAC_POWER_STATUS_MASK		0x80
    +#define AIC3262_RDAC_POWER_STATUS_MASK		0x08
    +#define AIC3262_DAC_POWER_MASK		0x88
    +#define AIC3262_DAC_FLAG		MAKE_REG(0, 0, 37)
    +#define AIC3262_LADC_POWER_MASK		0x40
    +#define AIC3262_RADC_POWER_MASK		0x04
    +#define AIC3262_ADC_POWER_MASK		0x44
    +#define AIC3262_ADC_FLAG                MAKE_REG(0, 0, 36)
    +#define AIC3262_JACK_WITH_STEREO_HS	(0b00000010)
    +#define AIC3262_JACK_WITH_MIC		(0b00110000)
    +#define AIC3262_HEADSET_NOT_INSERTED	(0b00000011)
    +#define AIC3262_JACK_TYPE_MASK		(0b00110000) 
    +#define AIC3262_JACK_NOT_INSERTED	(0b00000000)
    +#define AIC3262_JACK_WITHOUT_MIC	(0b00010000)
    +
    +#define AIC3262_INT_STICKY_FLAG1		MAKE_REG(0, 0, 42)
    +#define AIC3262_LEFT_DAC_OVERFLOW_INT	0x80
    +#define AIC3262_RIGHT_DAC_OVERFLOW_INT	0x40
    +#define AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT	0x20
    +#define AIC3262_LEFT_ADC_OVERFLOW_INT	0x08
    +#define AIC3262_RIGHT_ADC_OVERFLOW_INT	0x04
    +#define AIC3262_MINIDSP_A_BARREL_SHIFT_OVERFLOW_INT	0x02
    +#define AIC3262_INT_STICKY_FLAG2		MAKE_REG(0, 0, 44)
    +#define AIC3262_LEFT_OUTPUT_DRIVER_OVERCURRENT_INT	0x80
    +#define AIC3262_RIGHT_OUTPUT_DRIVER_OVERCURRENT_INT	0x40
    +#define AIC3262_BUTTON_PRESS_INT			0x20
    +#define AIC3262_HEADSET_PLUG_UNPLUG_INT			0x10
    +#define AIC3262_LEFT_DRC_THRES_INT			0x08
    +#define AIC3262_RIGHT_DRC_THRES_INT			0x04
    +#define AIC3262_MINIDSP_D_STD_INT			0x02
    +#define AIC3262_RIGHT_DRC_AUX_INT			0x01
    +#define AIC3262_INT_STICKY_FLAG3		MAKE_REG(0, 0, 45)
    +#define AIC3262_SPK_OVER_CURRENT_INT		0x80
    +#define AIC3262_LEFT_AGC_NOISE_INT			0x40
    +#define AIC3262_RIGHT_AGC_NOISE_INT			0x20
    +#define AIC3262_INT1_CNTL		MAKE_REG(0, 0, 48)
    +#define AIC3262_HEADSET_IN_MASK		0x80
    +#define AIC3262_BUTTON_PRESS_MASK	0x40
    +#define AIC3262_DAC_DRC_THRES_MASK	0x20
    +#define AIC3262_AGC_NOISE_MASK		0x10
    +#define AIC3262_OVER_CURRENT_MASK	0x08
    +#define AIC3262_OVERFLOW_MASK		0x04
    +#define AIC3262_SPK_OVERCURRENT_MASK	0x02
    +#define AIC3262_INT2_CNTL		MAKE_REG(0, 0, 49)
    +#define AIC3262_INT_FMT			MAKE_REG(0, 0, 51)
    +
    +#define AIC3262_DAC_PRB			MAKE_REG(0, 0, 60)
    +#define AIC3262_ADC_PRB			MAKE_REG(0, 0, 61)
    +#define AIC3262_PASI_DAC_DP_SETUP	MAKE_REG(0, 0, 63)
    +
    +#define AIC3262_DAC_MVOL_CONF		MAKE_REG(0, 0, 64)
    +#define AIC3262_DAC_LR_MUTE_MASK	0xc
    +#define AIC3262_DAC_LR_MUTE		0xc
    +
    +#define AIC3262_DAC_LVOL		MAKE_REG(0, 0, 65)
    +#define AIC3262_DAC_RVOL		MAKE_REG(0, 0, 66)
    +#define AIC3262_HP_DETECT		MAKE_REG(0, 0, 67)
    +#define AIC3262_DRC_CNTL_R1		MAKE_REG(0, 0, 68)
    +#define AIC3262_DRC_CNTL_R2		MAKE_REG(0, 0, 69)
    +#define AIC3262_DRC_CNTL_R3		MAKE_REG(0, 0, 70)
    +#define AIC3262_BEEP_CNTL_R1		MAKE_REG(0, 0, 71)
    +#define AIC3262_BEEP_CNTL_R2		MAKE_REG(0, 0, 72)
    +
    +#define AIC3262_ADC_CHANNEL_POW		MAKE_REG(0, 0, 81)
    +#define AIC3262_ADC_FINE_GAIN		MAKE_REG(0, 0, 82)
    +#define AIC3262_LADC_VOL		MAKE_REG(0, 0, 83)
    +#define AIC3262_RADC_VOL		MAKE_REG(0, 0, 84)
    +#define AIC3262_ADC_PHASE		MAKE_REG(0, 0, 85)
    +
    +#define AIC3262_LAGC_CNTL		MAKE_REG(0, 0, 86)
    +#define AIC3262_LAGC_CNTL_R2		MAKE_REG(0, 0, 87)
    +#define AIC3262_LAGC_CNTL_R3		MAKE_REG(0, 0, 88)
    +#define AIC3262_LAGC_CNTL_R4		MAKE_REG(0, 0, 89)
    +#define AIC3262_LAGC_CNTL_R5		MAKE_REG(0, 0, 90)
    +#define AIC3262_LAGC_CNTL_R6		MAKE_REG(0, 0, 91)
    +#define AIC3262_LAGC_CNTL_R7		MAKE_REG(0, 0, 92)
    +#define AIC3262_LAGC_CNTL_R8		MAKE_REG(0, 0, 93)
    +
    +#define AIC3262_RAGC_CNTL		MAKE_REG(0, 0, 94)
    +#define AIC3262_RAGC_CNTL_R2		MAKE_REG(0, 0, 95)
    +#define AIC3262_RAGC_CNTL_R3		MAKE_REG(0, 0, 96)
    +#define AIC3262_RAGC_CNTL_R4		MAKE_REG(0, 0, 97)
    +#define AIC3262_RAGC_CNTL_R5		MAKE_REG(0, 0, 98)
    +#define AIC3262_RAGC_CNTL_R6		MAKE_REG(0, 0, 99)
    +#define AIC3262_RAGC_CNTL_R7		MAKE_REG(0, 0, 100)
    +#define AIC3262_RAGC_CNTL_R8		MAKE_REG(0, 0, 101)
    +#define AIC3262_MINIDSP_ACCESS_CTRL	MAKE_REG(0, 0, 121)
    +#define AIC3262_DEVICE_ID		MAKE_REG(0, 0, 125)
    +/* ****************** Page 1 Registers **************************************/
    +#define AIC3262_PAGE_1			128
    +
    +#define AIC3262_POWER_CONF		MAKE_REG(0, 1, 1)
    +
    +#define AIC3262_AVDD_TO_DVDD_MASK	(0b00001000)
    +#define	AIC3262_AVDD_TO_DVDD		0x8
    +#define AIC3262_EXT_ANALOG_SUPPLY_MASK	(0b00000100)
    +#define	AIC3262_EXT_ANALOG_SUPPLY_OFF	0x4
    +
    +#define AIC3262_LDAC_PTM		MAKE_REG(0, 1, 3)
    +#define AIC3262_RDAC_PTM		MAKE_REG(0, 1, 4)
    +#define AIC3262_CM_REG			MAKE_REG(0, 1, 8)
    +#define AIC3262_HP_CTL			MAKE_REG(0, 1, 9)
    +#define AIC3262_HP_DEPOP		MAKE_REG(0, 1, 11)
    +#define AIC3262_RECV_DEPOP		MAKE_REG(0, 1, 12)
    +#define AIC3262_MA_CNTL			MAKE_REG(0, 1, 17)
    +#define AIC3262_LADC_PGA_MAL_VOL	MAKE_REG(0, 1, 18)
    +#define AIC3262_RADC_PGA_MAR_VOL	MAKE_REG(0, 1, 19)
    +
    +#define AIC3262_LINE_AMP_CNTL_R1	MAKE_REG(0, 1, 22)
    +#define AIC3262_LINE_AMP_CNTL_R2	MAKE_REG(0, 1, 23)
    +
    +#define AIC3262_HP_AMP_CNTL_R1		MAKE_REG(0, 1, 27)
    +#define AIC3262_HP_AMP_CNTL_R2		MAKE_REG(0, 1, 28)
    +#define AIC3262_HP_AMP_CNTL_R3		MAKE_REG(0, 1, 29)
    +
    +#define AIC3262_HPL_VOL			MAKE_REG(0, 1, 31)
    +#define AIC3262_HPR_VOL			MAKE_REG(0, 1, 32)
    +#define AIC3262_INT1_SEL_L		MAKE_REG(0, 1, 34)
    +#define AIC3262_CHARGE_PUMP_CNTL	MAKE_REG(0, 1, 35)
    +#define AIC3262_RAMP_CNTL_R1		MAKE_REG(0, 1, 36)
    +#define AIC3262_RAMP_CNTL_R2		MAKE_REG(0, 1, 37)
    +#define AIC3262_IN1L_SEL_RM		MAKE_REG(0, 1, 38)
    +#define AIC3262_IN1R_SEL_RM		MAKE_REG(0, 1, 39)
    +#define AIC3262_REC_AMP_CNTL_R5		MAKE_REG(0, 1, 40)
    +#define AIC3262_RAMPR_VOL		MAKE_REG(0, 1, 41)
    +#define AIC3262_RAMP_TIME_CNTL		MAKE_REG(0, 1, 42)
    +#define AIC3262_SPK_AMP_CNTL_R1		MAKE_REG(0, 1, 45)
    +#define AIC3262_SPK_AMP_CNTL_R2		MAKE_REG(0, 1, 46)
    +#define AIC3262_SPK_AMP_CNTL_R3		MAKE_REG(0, 1, 47)
    +#define AIC3262_SPK_AMP_CNTL_R4		MAKE_REG(0, 1, 48)
    +#define AIC3262_MIC_BIAS_CNTL		MAKE_REG(0, 1, 51)
    +
    +#define AIC3262_LMIC_PGA_PIN		MAKE_REG(0, 1, 52)
    +#define AIC3262_LMIC_PGA_PM_IN4		MAKE_REG(0, 1, 53)
    +#define AIC3262_LMIC_PGA_MIN		MAKE_REG(0, 1, 54)
    +#define AIC3262_RMIC_PGA_PIN		MAKE_REG(0, 1, 55)
    +#define AIC3262_RMIC_PGA_PM_IN4		MAKE_REG(0, 1, 56)
    +#define AIC3262_RMIC_PGA_MIN		MAKE_REG(0, 1, 57)
    +#define AIC3262_HP_FLAG		        MAKE_REG(0, 1, 66)
    +#define AIC3262_SPKL_POWER_MASK		0x2
    +#define AIC3262_SPKR_POWER_MASK		0x1
    +#define AIC3262_HPL_POWER_MASK		(0b00000010)
    +#define AIC3262_HPR_POWER_MASK		(0b00000001)
    +#define AIC3262_SPKL_POWER_STATUS_MASK		0x2
    +#define AIC3262_SPKR_POWER_STATUS_MASK		0x1
    +#define AIC3262_HPL_POWER_STATUS_MASK		0x20
    +#define AIC3262_HPR_POWER_STATUS_MASK		0x10
    +
    +#define AIC3262_HP_STAGE_MASK		(0b01100000)
    +#define AIC3262_HP_STAGE_100		(0)
    +#define AIC3262_HP_STAGE_75		(1)
    +#define AIC3262_HP_STAGE_50		(2)
    +#define AIC3262_HP_STAGE_25		(3)
    +#define AIC3262_HP_STAGE_SHIFT		(5)
    +#define AIC3262_DYNAMIC_OFFSET_CALIB_MASK	(0b00100000)
    +#define AIC3262_DYNAMIC_OFFSET_CALIB		(0b00100000)
    +
    +/* MIC PGA Gain Registers */
    +#define AIC3262_MICL_PGA		MAKE_REG(0, 1, 59)
    +#define AIC3262_MICR_PGA		MAKE_REG(0, 1, 60)
    +#define AIC3262_HEADSET_TUNING1_REG	MAKE_REG(0, 1, 119)
    +#define AIC3262_HEADSET_DETECTOR_PULSE_MASK (0b11000000)
    +#define AIC3262_HEADSET_DETECTOR_PULSE_RESET (0b10000000)
    +#define AIC3262_MIC_PWR_DLY		MAKE_REG(0, 1, 121)
    +#define AIC3262_REF_PWR_DLY		MAKE_REG(0, 1, 122)
    +#define AIC3262_CHIP_REF_PWR_ON_MASK	0x4
    +#define AIC3262_CHIP_REF_PWR_ON		0x4
    +/* ****************** Page 4 Registers **************************************/
    +#define AIC3262_PAGE_4			512
    +#define AIC3262_ASI1_BUS_FMT		MAKE_REG(0, 4, 1)
    +#define AIC3262_ASI_SELECTION_MASK	(0b11100000)
    +#define AIC3262_ASI_DATA_WORD_LENGTH_MASK	(0b00011000)
    +#define AIC3262_ASI1_BCLK_N_MASK	(0b01111111)
    +#define AIC3262_ASI1_WCLK_N_MASK	(0b01111111)
    +#define AIC3262_ASI1_CHNL_MASK		(0b11000000)
    +#define AIC3262_ASI1_DAC_OUT_OFFSET	(0b00000001)
    +#define AIC3262_ASI1_LCH_OFFSET		MAKE_REG(0, 4, 2)
    +#define AIC3262_ASI1_RCH_OFFSET		MAKE_REG(0, 4, 3)
    +#define AIC3262_ASI1_CHNL_SETUP		MAKE_REG(0, 4, 4)
    +#define AIC3262_ASI1_MULTI_CH_SETUP_R1	MAKE_REG(0, 4, 5)
    +#define AIC3262_ASI1_MULTI_CH_SETUP_R2	MAKE_REG(0, 4, 6)
    +#define AIC3262_ASI1_ADC_INPUT_CNTL	MAKE_REG(0, 4, 7)
    +#define AIC3262_ASI1_DAC_OUT_CNTL	MAKE_REG(0, 4, 8)
    +#define AIC3262_ASI1_ADC_OUT_TRISTATE	MAKE_REG(0, 4, 9)
    +#define AIC3262_ASI1_BWCLK_CNTL_REG	MAKE_REG(0, 4, 10)
    +#define AIC3262_ASI1_BCLK_N_CNTL	MAKE_REG(0, 4, 11)
    +#define AIC3262_ASI1_BCLK_N		MAKE_REG(0, 4, 12)
    +#define AIC3262_ASI1_WCLK_N		MAKE_REG(0, 4, 13)
    +#define AIC3262_ASI1_BWCLK_OUT_CNTL	MAKE_REG(0, 4, 14)
    +#define AIC3262_ASI1_DOUT_CNTL		MAKE_REG(0, 4, 15)
    +#define AIC3262_ASI2_BUS_FMT	        MAKE_REG(0, 4, 17)
    +#define AIC3262_ASI2_LCH_OFFSET		MAKE_REG(0, 4, 18)
    +#define AIC3262_ASI2_ADC_INPUT_CNTL	MAKE_REG(0, 4, 23)
    +#define AIC3262_ASI2_DAC_OUT_CNTL	MAKE_REG(0, 4, 24)
    +#define AIC3262_ASI2_BWCLK_CNTL_REG	MAKE_REG(0, 4, 26)
    +#define AIC3262_ASI2_BCLK_N_CNTL	MAKE_REG(0, 4, 27)
    +#define AIC3262_ASI2_BCLK_N		MAKE_REG(0, 4, 28)
    +#define AIC3262_ASI2_WCLK_N		MAKE_REG(0, 4, 29)
    +#define AIC3262_ASI2_BWCLK_OUT_CNTL	MAKE_REG(0, 4, 30)
    +#define AIC3262_ASI2_DOUT_CNTL		MAKE_REG(0, 4, 31)
    +#define AIC3262_ASI3_BUS_FMT		MAKE_REG(0, 4, 33)
    +#define AIC3262_ASI3_LCH_OFFSET		MAKE_REG(0, 4, 34)
    +#define AIC3262_ASI3_ADC_INPUT_CNTL	MAKE_REG(0, 4, 39)
    +#define AIC3262_ASI3_DAC_OUT_CNTL	MAKE_REG(0, 4, 40)
    +#define AIC3262_ASI3_BWCLK_CNTL_REG	MAKE_REG(0, 4, 42)
    +#define AIC3262_ASI3_BCLK_N_CNTL	MAKE_REG(0, 4, 43)
    +#define AIC3262_ASI3_BCLK_N		MAKE_REG(0, 4, 44)
    +#define AIC3262_ASI3_WCLK_N		MAKE_REG(0, 4, 45)
    +#define AIC3262_ASI3_BWCLK_OUT_CNTL	MAKE_REG(0, 4, 46)
    +#define AIC3262_ASI3_DOUT_CNTL		MAKE_REG(0, 4, 47)
    +#define AIC3262_DMIC_INPUT_CNTL		MAKE_REG(0, 4, 101)
    +#define AIC3262_GPIO1_IO_CNTL		MAKE_REG(0, 4, 86)
    +#define AIC3262_GPIO_D6_D2		(0b01111100)
    +#define AIC3262_GPIO_D2_SHIFT		(2)
    +#define AIC3262_GPIO_D1_SHIFT		(1)
    +#define AIC3262_GPIO_D4_SHIFT		(4)
    +#define AIC3262_GPIO2_IO_CNTL		MAKE_REG(0, 4, 87)
    +#define AIC3262_GPI1_EN			MAKE_REG(0, 4, 91)
    +#define AIC3262_GPI1_D2_D1		(0b00000110)
    +#define AIC3262_GPI2_D5_D4		(0b00110000)
    +#define AIC3262_GPI2_EN			MAKE_REG(0, 4, 92)
    +#define AIC3262_GPO1_OUT_CNTL		MAKE_REG(0, 4, 96)
    +#define AIC3262_GPO1_D4_D1		(0b00011110)
    +#define AIC3262_DMIC_INPUT_CONTROL	MAKE_REG(0, 4, 101)
    +#define AIC3262_DMIC_CONFIGURE_MASK	(0b00011111)
    +#define AIC3262_DMIC_CONFIGURE_SHIFT	(0)
    +#define AIC3262_DMIC_GPI2_LEFT_GPI2_RIGHT	(1)
    +#define AIC3262_MINIDSP_DATA_PORT_CNTL	MAKE_REG(0, 4, 118)
    +
    +#define AIC3262_DAC_ASI_LR_UNMUTE_MASK	0x50
    +#define AIC3262_DAC_ASI_LR_UNMUTE	0x50
    +#define AIC3262_WCLK_BCLK_MASTER_MASK (0b00100110)
    +#define AIC3262_WCLK_MASTER_MASK (0b00100000)
    +#define AIC3262_BCLK_MASTER_MASK (0b00000100)
    +#define AIC3262_BCLK_OFFSET_MASK (0b11111111)
    +#define AIC3262_ASI_INTERFACE_MASK (0b11100000)
    +#define AIC3262_WCLK_OUT_MASK (0b00100000)
    +#define AIC3262_BCLK_OUT_MASK (0b00000100)
    +#define AIC3262_BCLK_INV_MASK (0b00000010)
    +
    +#define AIC3262_ADC_ADAPTIVE_CRAM_REG    MAKE_REG(40, 0, 1)
    +#define AIC3262_DAC_ADAPTIVE_BANK1_REG   MAKE_REG(80, 0, 1)
    +#define AIC3262_DAC_ADAPTIVE_BANK2_REG   MAKE_REG(82, 0, 1)
    +#define AIC3262_ADC_DATAPATH_SETUP      MAKE_REG(0, 0, 81)
    +#define AIC3262_DAC_DATAPATH_SETUP      MAKE_REG(0, 0, 63)
    +
    +#endif
    +
    diff --git a/include/linux/mfd/tlv320aic3xxx-core.h b/include/linux/mfd/tlv320aic3xxx-core.h
    new file mode 100644
    index 000000000..f6359f3a1
    --- /dev/null
    +++ b/include/linux/mfd/tlv320aic3xxx-core.h
    @@ -0,0 +1,291 @@
    +/*
    + * MFD driver for aic3262
    + *
    + * Author:      Mukund Navada <navada@ti.com>
    + *              Mehar Bajwa <mehar.bajwa@ti.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#ifndef __MFD_AIC3262_CORE_H__
    +#define __MFD_AIC3262_CORE_H__
    +
    +#include <linux/interrupt.h>
    +#include <linux/mfd/core.h>
    +enum aic3xxx_type {
    +	TLV320AIC3262 = 0,
    +	TLV320AIC3266 = 1,
    +	TLV320AIC3285 = 2,
    +	TLV320AIC3268 = 3,
    +};
    +
    +#define AIC3262_IRQ_HEADSET_DETECT	0
    +#define AIC3262_IRQ_BUTTON_PRESS	1
    +#define AIC3262_IRQ_DAC_DRC		2
    +#define AIC3262_IRQ_AGC_NOISE		3
    +#define AIC3262_IRQ_OVER_CURRENT	4
    +#define AIC3262_IRQ_OVERFLOW_EVENT	5
    +#define AIC3262_IRQ_SPEAKER_OVER_TEMP	6
    +
    +#define AIC3262_GPIO1			7
    +#define AIC3262_GPIO2			8
    +#define AIC3262_GPI1			9
    +#define AIC3262_GPI2			10
    +#define AIC3262_GPO1			11
    +#define AIC3285_GPIO3			9
    +#define AIC3285_GPIO4			10
    +#define AIC3285_GPIO5			11
    +#define AIC3285_GPIO6			12
    +#define AIC3285_GPIO7			13
    +#define AIC3285_GPIO8			14
    +#define AIC3285_GPIO9			15
    +#define AIC3285_GPIO10			16
    +#define AIC3285_GPIO11			17
    +#define AIC3285_GPIO12			18
    +#define AIC3285_GPO1			19
    +
    +struct aic3262_codec_data {
    +	u16 hs_left_step;
    +	u16 hs_right_step;
    +	u16 hf_left_step;
    +	u16 hf_right_step;
    +};
    +
    +struct aic3262_platform_data {
    +	int audpwron_gpio;	/* audio power-on gpio */
    +	unsigned int irq_base;
    +
    +	struct aic3262_codec_data *codec;
    +};
    +
    +union aic3xxx_reg_union {
    +	struct aic3xxx_reg {
    +		u8 offset;
    +		u8 page;
    +		u8 book;
    +		u8 reserved;
    +	} aic3xxx_register;
    +	unsigned int aic3xxx_register_int;
    +};
    +
    +/****************************             ************************************/
    +
    +/*
    + *****************************************************************************
    + * Structures Definitions
    + *****************************************************************************
    + */
    +/*
    + *----------------------------------------------------------------------------
    + * @struct  aic3262_setup_data |
    + *          i2c specific data setup for AIC3262.
    + * @field   unsigned short |i2c_address |
    + *          Unsigned short for i2c address.
    + *----------------------------------------------------------------------------
    + */
    +struct aic3262_setup_data {
    +	unsigned short i2c_address;
    +};
    +
    +/* GPIO API */
    +#define AIC3262_NUM_GPIO 5	/* include 2 GPI and 1 GPO pins */
    +enum {
    +	AIC3262_GPIO1_FUNC_DISABLED =		0,
    +	AIC3262_GPIO1_FUNC_INPUT =		1,
    +	AIC3262_GPIO1_FUNC_OUTPUT =		3,
    +	AIC3262_GPIO1_FUNC_CLOCK_OUTPUT =	4,
    +	AIC3262_GPIO1_FUNC_INT1_OUTPUT =	5,
    +	AIC3262_GPIO1_FUNC_INT2_OUTPUT =	6,
    +	AIC3285_GPIO_FUNC_DSD_CHAN1_OUTPUT = 	7,
    +	AIC3285_GPIO_FUNC_DSD_CHAN2_OUTPUT = 	8,
    +	AIC3285_GPIO_FUNC_DAC_MOD_CLK_OUTPUT = 	9,
    +	AIC3262_GPIO1_FUNC_ADC_MOD_CLK_OUTPUT =	10,
    +	AIC3262_GPIO1_FUNC_SAR_ADC_INTERRUPT =	12,
    +	AIC3262_GPIO1_FUNC_ASI1_DATA_OUTPUT =	15,
    +	AIC3262_GPIO1_FUNC_ASI1_WCLK =		16,
    +	AIC3262_GPIO1_FUNC_ASI1_BCLK =		17,
    +	AIC3262_GPIO1_FUNC_ASI2_WCLK =		18,
    +	AIC3262_GPIO1_FUNC_ASI2_BCLK =		19,
    +	AIC3262_GPIO1_FUNC_ASI3_WCLK =		20,
    +	AIC3262_GPIO1_FUNC_ASI3_BCLK =		21,
    +	AIC3285_GPIO_I2C_MASTER_SCL =		30,
    +	AIC3285_GPIO_I2C_MASTER_SDA =		30,
    +};
    +
    +enum {
    +	AIC3262_GPIO2_FUNC_DISABLED =		0,
    +	AIC3262_GPIO2_FUNC_INPUT =		1,
    +	AIC3262_GPIO2_FUNC_OUTPUT =		3,
    +	AIC3262_GPIO2_FUNC_CLOCK_OUTPUT =	4,
    +	AIC3262_GPIO2_FUNC_INT1_OUTPUT =	5,
    +	AIC3262_GPIO2_FUNC_INT2_OUTPUT =	6,
    +	AIC3262_GPIO2_FUNC_ADC_MOD_CLK_OUTPUT = 10,
    +	AIC3262_GPIO2_FUNC_SAR_ADC_INTERRUPT =	12,
    +	AIC3262_GPIO2_FUNC_ASI1_DATA_OUTPUT =	15,
    +	AIC3262_GPIO2_FUNC_ASI1_WCLK =		16,
    +	AIC3262_GPIO2_FUNC_ASI1_BCLK =		17,
    +	AIC3262_GPIO2_FUNC_ASI2_WCLK =		18,
    +	AIC3262_GPIO2_FUNC_ASI2_BCLK =		19,
    +	AIC3262_GPIO2_FUNC_ASI3_WCLK =		20,
    +	AIC3262_GPIO2_FUNC_ASI3_BCLK =		21
    +};
    +enum {
    +	AIC3262_GPO1_FUNC_DISABLED =		0,
    +	AIC3262_GPO1_FUNC_MSO_OUTPUT_FOR_SPI =	1,
    +	AIC3262_GPO1_FUNC_GENERAL_PURPOSE_OUTPUT = 2,
    +	AIC3262_GPO1_FUNC_CLOCK_OUTPUT =	3,
    +	AIC3262_GPO1_FUNC_INT1_OUTPUT =	4,
    +	AIC3262_GPO1_FUNC_INT2_OUTPUT =	5,
    +	AIC3262_GPO1_FUNC_ADC_MOD_CLK_OUTPUT =	7,
    +	AIC3262_GPO1_FUNC_SAR_ADC_INTERRUPT =	12,
    +	AIC3262_GPO1_FUNC_ASI1_DATA_OUTPUT =	15,
    +};
    +/*
    + *----------------------------------------------------------------------------
    + * @struct  aic3262_configs |
    + *          AIC3262 initialization data which has register offset and register
    + *          value.
    + * @field   u8 | book_no |
    + *          AIC3262 Book Number Offsets required for initialization..
    + * @field   u16 | reg_offset |
    + *          AIC3262 Register offsets required for initialization..
    + * @field   u8 | reg_val |
    + *          value to set the AIC3262 register to initialize the AIC3262.
    + *---------------------------------------------------------------------------
    + */
    +struct aic3xxx_configs {
    +	u8 book_no;
    +	u16 reg_offset;
    +	u8 reg_val;
    +};
    +
    +/*
    + *----------------------------------------------------------------------------
    + * @struct  aic3262_rate_divs |
    + *          Setting up the values to get different freqencies
    + *
    + * @field   u32 | mclk |
    + *          Master clock
    + * @field   u32 | rate |
    + *          sample rate
    + * @field   u8 | p_val |
    + *          value of p in PLL
    + * @field   u32 | pll_j |
    + *          value for pll_j
    + * @field   u32 | pll_d |
    + *          value for pll_d
    + * @field   u32 | dosr |
    + *          value to store dosr
    + * @field   u32 | ndac |
    + *          value for ndac
    + * @field   u32 | mdac |
    + *          value for mdac
    + * @field   u32 | aosr |
    + *          value for aosr
    + * @field   u32 | nadc |
    + *          value for nadc
    + * @field   u32 | madc |
    + *          value for madc
    + * @field   u32 | blck_N |
    + *          value for block N
    + */
    +struct aic3xxx {
    +	struct mutex io_lock;
    +	struct mutex irq_lock;
    +	enum aic3xxx_type type;
    +	struct device *dev;
    +	struct regmap *regmap;
    +	struct aic3xxx_pdata *pdata;
    +	void *control_data;
    +	unsigned int irq;
    +	unsigned int irq_base;
    +	u8 irq_masks_cur;
    +	u8 irq_masks_cache;
    +	/* Used over suspend/resume */
    +	bool suspended;
    +	u8 book_no;
    +	u8 page_no;
    +};
    +
    +struct aic3262_gpio_setup {
    +	u8 used;		/* GPIO, GPI and GPO is used in the board, */
    +				/* used = 1 else 0 */
    +	u8 in;			/* GPIO is used as input, in = 1 else in = 0 */
    +				/* GPI in = 1, GPO in = 0 */
    +	unsigned int in_reg;	/* if GPIO is input,
    +					register to write the mask. */
    +	u8 in_reg_bitmask;	/* bitmask for 'value' to be
    +					written into in_reg */
    +	u8 in_reg_shift;	/* bits to shift to write 'value'
    +					into in_reg */
    +	u8 value;		/* value to be written
    +					gpio_control_reg if GPIO */
    +				/* is output, in_reg if its input */
    +};
    +
    +struct aic3xxx_pdata {
    +	unsigned int audio_mclk1;
    +	unsigned int audio_mclk2;
    +	unsigned int gpio_irq;	/* whether AIC3262 interrupts the host AP on */
    +				/* a GPIO pin of AP */
    +	unsigned int gpio_reset;/* is the codec being reset by a gpio*/
    +				/* [host] pin, if yes provide the number. */
    +	struct aic3262_gpio_setup *gpio;/* all gpio configuration */
    +	int naudint_irq;	/* audio interrupt */
    +	unsigned int irq_base;
    +};
    +
    +static inline int aic3xxx_request_irq(struct aic3xxx *aic3xxx, int irq,
    +				      irq_handler_t handler,
    +				      unsigned long irqflags, const char *name,
    +				      void *data)
    +{
    +	if (!aic3xxx->irq_base)
    +		return -EINVAL;
    +
    +	return request_threaded_irq(aic3xxx->irq_base + irq, NULL, handler,
    +				    irqflags, name, data);
    +}
    +
    +static inline int aic3xxx_free_irq(struct aic3xxx *aic3xxx, int irq, void *data)
    +{
    +	if (!aic3xxx->irq_base)
    +		return -EINVAL;
    +
    +	free_irq(aic3xxx->irq_base + irq, data);
    +	return 0;
    +}
    +
    +/* Device I/O API */
    +int aic3xxx_reg_read(struct aic3xxx *aic3xxx, unsigned int reg);
    +int aic3xxx_reg_write(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      unsigned char val);
    +int aic3xxx_set_bits(struct aic3xxx *aic3xxx, unsigned int reg,
    +		     unsigned char mask, unsigned char val);
    +int aic3xxx_bulk_read(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      int count, u8 *buf);
    +int aic3xxx_bulk_write(struct aic3xxx *aic3xxx, unsigned int reg,
    +		       int count, const u8 *buf);
    +int aic3xxx_wait_bits(struct aic3xxx *aic3xxx, unsigned int reg,
    +		      unsigned char mask, unsigned char val, int delay,
    +		      int counter);
    +
    +int aic3xxx_irq_init(struct aic3xxx *aic3xxx);
    +void aic3xxx_irq_exit(struct aic3xxx *aic3xxx);
    +int aic3xxx_device_init(struct aic3xxx *aic3xxx, int irq);
    +void aic3xxx_device_exit(struct aic3xxx *aic3xxx);
    +
    +#endif /* End of __MFD_AIC3262_CORE_H__ */
    diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
    index 0904827e2..24d5847d8 100644
    --- a/sound/soc/codecs/Kconfig
    +++ b/sound/soc/codecs/Kconfig
    @@ -240,6 +240,7 @@ config SND_SOC_ALL_CODECS
     	imply SND_SOC_TLV320AIC32X4_SPI
     	imply SND_SOC_TLV320AIC3X_I2C
     	imply SND_SOC_TLV320AIC3X_SPI
    +	imply SND_SOC_AIC3262
     	imply SND_SOC_TPA6130A2
     	imply SND_SOC_TLV320DAC33
     	imply SND_SOC_TSCS42XX
    @@ -1706,6 +1707,13 @@ config SND_SOC_TLV320ADCX140
     	  Add support for Texas Instruments tlv320adc3140, tlv320adc5140 and
     	  tlv320adc6140 quad channel ADCs.
     
    +config SND_SOC_AIC3262
    +	tristate "Texas Instrument TLV320AIC3262 CODEC chip"
    +	depends on I2C
    +	select REGMAP_I2C
    +	help
    +	  add codec driver for tlv320aic3262
    +
     config SND_SOC_TS3A227E
     	tristate "TI Headset/Mic detect and keypress chip"
     	depends on I2C
    diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
    index 71d3ce586..4155539ad 100644
    --- a/sound/soc/codecs/Makefile
    +++ b/sound/soc/codecs/Makefile
    @@ -271,6 +271,7 @@ snd-soc-tlv320aic3x-i2c-objs := tlv320aic3x-i2c.o
     snd-soc-tlv320aic3x-spi-objs := tlv320aic3x-spi.o
     snd-soc-tlv320dac33-objs := tlv320dac33.o
     snd-soc-tlv320adcx140-objs := tlv320adcx140.o
    +snd-soc-tlv320aic3262-objs := tlv320aic326x.o aic3xxx/aic3xxx_cfw_ops.o
     snd-soc-tscs42xx-objs := tscs42xx.o
     snd-soc-tscs454-objs := tscs454.o
     snd-soc-ts3a227e-objs := ts3a227e.o
    @@ -629,6 +630,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC3X_I2C)	+= snd-soc-tlv320aic3x-i2c.o
     obj-$(CONFIG_SND_SOC_TLV320AIC3X_SPI)	+= snd-soc-tlv320aic3x-spi.o
     obj-$(CONFIG_SND_SOC_TLV320DAC33)	+= snd-soc-tlv320dac33.o
     obj-$(CONFIG_SND_SOC_TLV320ADCX140)	+= snd-soc-tlv320adcx140.o
    +obj-$(CONFIG_SND_SOC_AIC3262)	+= snd-soc-tlv320aic3262.o
     obj-$(CONFIG_SND_SOC_TSCS42XX)	+= snd-soc-tscs42xx.o
     obj-$(CONFIG_SND_SOC_TSCS454)	+= snd-soc-tscs454.o
     obj-$(CONFIG_SND_SOC_TS3A227E)	+= snd-soc-ts3a227e.o
    diff --git a/sound/soc/codecs/aic3xxx/aic3xxx_cfw.h b/sound/soc/codecs/aic3xxx/aic3xxx_cfw.h
    new file mode 100644
    index 000000000..2012d510f
    --- /dev/null
    +++ b/sound/soc/codecs/aic3xxx/aic3xxx_cfw.h
    @@ -0,0 +1,529 @@
    +/*
    + *  aic3xxx_cfw.h  --  SoC audio for TI OMAP44XX SDP
    + *                      Codec Firmware Declarations
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#ifndef CFW_FIRMWARE_H_
    +#define CFW_FIRMWARE_H_
    +
    +
    +#define CFW_FW_MAGIC 0xC0D1F1ED
    +
    +
    +/** \defgroup pd Arbitrary Limitations */
    +/* @{ */
    +#ifndef CFW_MAX_ID
    +#    define CFW_MAX_ID          (64)	/**<Max length of string identifies*/
    +#    define CFW_MAX_VARS       (256)	/**<Number of "variables" alive at the*/
    +					/**<same time in an acx file*/
    +#endif
    +
    +/* @} */
    +
    +
    +
    +/** \defgroup st Enums, Flags, Macros and Supporting Types */
    +/* @{ */
    +
    +
    +/**
    + * Device Family Identifier
    + *
    + */
    +enum __attribute__ ((__packed__)) cfw_dfamily {
    +	CFW_DFM_TYPE_A,
    +	CFW_DFM_TYPE_B,
    +	CFW_DFM_TYPE_C
    +};
    +
    +/**
    + * Device Identifier
    + *
    + */
    +enum __attribute__ ((__packed__)) cfw_device {
    +	CFW_DEV_DAC3120,
    +	CFW_DEV_DAC3100,
    +	CFW_DEV_AIC3120,
    +	CFW_DEV_AIC3100,
    +	CFW_DEV_AIC3110,
    +	CFW_DEV_AIC3111,
    +	CFW_DEV_AIC36,
    +	CFW_DEV_AIC3206,
    +	CFW_DEV_AIC3204,
    +	CFW_DEV_AIC3254,
    +	CFW_DEV_AIC3256,
    +	CFW_DEV_AIC3253,
    +	CFW_DEV_AIC3212,
    +	CFW_DEV_AIC3262,
    +	CFW_DEV_AIC3017,
    +	CFW_DEV_AIC3008,
    +
    +	CFW_DEV_AIC3266,
    +	CFW_DEV_AIC3285,
    +};
    +
    +/**
    + * Transition Sequence Identifier
    + *
    + */
    +enum cfw_transition_t {
    +	CFW_TRN_INIT,
    +	CFW_TRN_RESUME,
    +	CFW_TRN_NEUTRAL,
    +	CFW_TRN_A_MUTE,
    +	CFW_TRN_D_MUTE,
    +	CFW_TRN_AD_MUTE,
    +	CFW_TRN_A_UNMUTE,
    +	CFW_TRN_D_UNMUTE,
    +	CFW_TRN_AD_UNMUTE,
    +	CFW_TRN_SUSPEND,
    +	CFW_TRN_EXIT,
    +	CFW_TRN_N
    +};
    +
    +#ifndef __cplusplus
    +static const char *const cfw_transition_id[] = {
    +	[CFW_TRN_INIT]     "INIT",
    +	[CFW_TRN_RESUME]   "RESUME",
    +	[CFW_TRN_NEUTRAL]  "NEUTRAL",
    +	[CFW_TRN_A_MUTE]   "A_MUTE",
    +	[CFW_TRN_D_MUTE]   "D_MUTE",
    +	[CFW_TRN_AD_MUTE]  "AD_MUTE",
    +	[CFW_TRN_A_UNMUTE] "A_UNMUTE",
    +	[CFW_TRN_D_UNMUTE] "D_UNMUTE",
    +	[CFW_TRN_AD_UNMUTE]"AD_UNMUTE",
    +	[CFW_TRN_SUSPEND]  "SUSPEND",
    +	[CFW_TRN_EXIT]     "EXIT",
    +};
    +#endif
    +
    +/* @} */
    +
    +/** \defgroup ds Data Structures */
    +/* @{ */
    +
    +
    +/**
    +* CFW Command
    +* These commands do not appear in the register
    +* set of the device.
    +*/
    +enum __attribute__ ((__packed__)) cfw_cmd_id {
    +	CFW_CMD_NOP = 0x80,
    +	CFW_CMD_DELAY,
    +	CFW_CMD_UPDTBITS,
    +	CFW_CMD_WAITBITS,
    +	CFW_CMD_LOCK,
    +	CFW_CMD_BURST,
    +	CFW_CMD_RBURST,
    +	CFW_CMD_LOAD_VAR_IM,
    +	CFW_CMD_LOAD_VAR_ID,
    +	CFW_CMD_STORE_VAR,
    +	CFW_CMD_COND,
    +	CFW_CMD_BRANCH,
    +	CFW_CMD_BRANCH_IM,
    +	CFW_CMD_BRANCH_ID,
    +	CFW_CMD_PRINT,
    +	CFW_CMD_OP_ADD = 0xC0,
    +	CFW_CMD_OP_SUB,
    +	CFW_CMD_OP_MUL,
    +	CFW_CMD_OP_DIV,
    +	CFW_CMD_OP_AND,
    +	CFW_CMD_OP_OR,
    +	CFW_CMD_OP_SHL,
    +	CFW_CMD_OP_SHR,
    +	CFW_CMD_OP_RR,
    +	CFW_CMD_OP_XOR,
    +	CFW_CMD_OP_NOT,
    +	CFW_CMD_OP_LNOT,
    +};
    +
    +/**
    +* CFW Delay
    +* Used for the cmd command delay
    +* Has one parameter of delay time in ms
    +*/
    +struct cfw_cmd_delay {
    +	u16 delay;
    +	enum cfw_cmd_id cid;
    +	u8 delay_fine;
    +};
    +
    +/**
    +* CFW Lock
    +* Take codec mutex to avoid clashing with DAPM operations
    +*/
    +struct cfw_cmd_lock {
    +	u16 lock;
    +	enum cfw_cmd_id cid;
    +	u8 unused;
    +};
    +
    +
    +/**
    + * CFW  UPDTBITS, WAITBITS, CHKBITS
    + * Both these cmd commands have same arguments
    + * cid will be used to specify which command it is
    + * has parameters of book, page, offset and mask
    + */
    +struct cfw_cmd_bitop {
    +	u16 unused1;
    +	enum cfw_cmd_id cid;
    +	u8 mask;
    +};
    +
    +/**
    + * CFW  CMD Burst header
    + * Burst writes inside command array
    + * Followed by burst address, first byte
    + */
    +struct cfw_cmd_bhdr {
    +	u16 len;
    +	enum cfw_cmd_id cid;
    +	u8 unused;
    +};
    +
    +/**
    + * CFW  CMD Burst
    + * Burst writes inside command array
    + * Followed by data to the extent indicated in previous len
    + * Can be safely cast to cfw_burst
    + */
    +struct cfw_cmd_burst {
    +	u8 book;
    +	u8 page;
    +	u8 offset;
    +	u8 data[1];
    +};
    +#define CFW_CMD_BURST_LEN(n) (2 + ((n) - 1 + 3)/4)
    +
    +/**
    + * CFW  CMD Scratch register
    + * For load
    + *  if (svar != dvar)
    + *      dvar = setbits(svar, mask) // Ignore reg
    + *  else
    + *      dvar = setbits(reg, mask)
    + * For store
    + *  if (svar != dvar)
    + *      reg = setbits(svar,  dvar)
    + *  else
    + *      reg =  setbits(svar, mask)
    + *
    + */
    +struct cfw_cmd_ldst {
    +	u8 dvar;
    +	u8 svar;
    +	enum cfw_cmd_id cid;
    +	u8 mask;
    +};
    +
    +/**
    + * CFW  CMD Conditional
    + * May only precede branch. Followed by nmatch+1 jump
    + * instructions
    + *   cond = svar&mask
    + * At each of the following nmatch+1 branch command
    + *   if (cond == match)
    + *       take the branch
    + */
    +struct cfw_cmd_cond {
    +	u8 svar;
    +	u8 nmatch;
    +	enum cfw_cmd_id cid;
    +	u8 mask;
    +};
    +#define CFW_CMD_COND_LEN(nm) (1 + ((nm)+1))
    +
    +/**
    + * CFW  CMD Goto
    + * For branch, break, continue and stop
    + */
    +struct cfw_cmd_branch {
    +	u16 address;
    +	enum cfw_cmd_id cid;
    +	u8 match;
    +};
    +
    +/**
    + * CFW  Debug print
    + * For diagnostics
    + */
    +struct cfw_cmd_print {
    +	u8 fmtlen;
    +	u8 nargs;
    +	enum cfw_cmd_id cid;
    +	char fmt[1];
    +};
    +
    +#define CFW_CMD_PRINT_LEN(p) (1 + ((p).fmtlen/4) + (((p).nargs + 3)/4))
    +#define CFW_CMD_PRINT_ARG(p) (1 + ((p).fmtlen/4))
    +
    +/**
    + * CFW  Arithmetic and logical operations
    + *  Bit 5 indicates if op1 is indirect
    + *  Bit 6 indicates if op2 is indirect
    + */
    +struct cfw_cmd_op {
    +	u8 op1;
    +	u8 op2;
    +	enum cfw_cmd_id cid;
    +	u8 dst;
    +};
    +#define CFW_CMD_OP1_ID     (1u<<5)
    +#define CFW_CMD_OP2_ID     (1u<<4)
    +
    +#define CFW_CMD_OP_START   CFW_CMD_OP_ADD
    +#define CFW_CMD_OP_END     (CFW_CMD_OP_LNOT|CFW_CMD_OP1_ID|CFW_CMD_OP2_ID)
    +#define CFW_CMD_OP_IS_UNARY(x) \
    +			(((x) == CFW_CMD_OP_NOT) || ((x) == CFW_CMD_OP_LNOT))
    +
    +
    +/**
    + * CFW Register
    + *
    + * A single reg write
    + *
    + */
    +union cfw_register {
    +	struct {
    +		u8 book;
    +		u8 page;
    +		u8 offset;
    +		u8 data;
    +	};
    +	u32 bpod;
    +};
    +
    +
    +
    +/**
    + * CFW Command
    + *
    + * Can be a either a
    + *      -# single register write, or
    + *      -# command
    + *
    + */
    +union cfw_cmd {
    +	struct {
    +		u16 unused1;
    +		enum cfw_cmd_id cid;
    +		u8 unused2;
    +	};
    +	union cfw_register reg;
    +	struct cfw_cmd_delay delay;
    +	struct cfw_cmd_lock lock;
    +	struct cfw_cmd_bitop bitop;
    +	struct cfw_cmd_bhdr bhdr;
    +	struct cfw_cmd_burst burst;
    +	struct cfw_cmd_ldst ldst;
    +	struct cfw_cmd_cond cond;
    +	struct cfw_cmd_branch branch;
    +	struct cfw_cmd_print print;
    +	u8     print_arg[4];
    +	struct cfw_cmd_op op;
    +};
    +
    +#define CFW_REG_IS_CMD(x) ((x).cid >= CFW_CMD_DELAY)
    +
    +/**
    + * CFW Block Type
    + *
    + * Block identifier
    + *
    + */
    +enum __attribute__ ((__packed__)) cfw_block_t {
    +	CFW_BLOCK_SYSTEM_PRE,
    +	CFW_BLOCK_A_INST,
    +	CFW_BLOCK_A_A_COEF,
    +	CFW_BLOCK_A_B_COEF,
    +	CFW_BLOCK_A_F_COEF,
    +	CFW_BLOCK_D_INST,
    +	CFW_BLOCK_D_A1_COEF,
    +	CFW_BLOCK_D_B1_COEF,
    +	CFW_BLOCK_D_A2_COEF,
    +	CFW_BLOCK_D_B2_COEF,
    +	CFW_BLOCK_D_F_COEF,
    +	CFW_BLOCK_SYSTEM_POST,
    +	CFW_BLOCK_N,
    +	CFW_BLOCK_INVALID,
    +};
    +#define CFW_BLOCK_D_A_COEF CFW_BLOCK_D_A1_COEF
    +#define CFW_BLOCK_D_B_COEF CFW_BLOCK_D_B1_COEF
    +
    +/**
    + * CFW Block
    + *
    + * A block of logically grouped sequences/commands/cmd-commands
    + *
    + */
    +struct cfw_block {
    +	enum cfw_block_t type;
    +	int ncmds;
    +	union cfw_cmd cmd[];
    +};
    +#define CFW_BLOCK_SIZE(ncmds) (sizeof(struct cfw_block) + \
    +				((ncmds)*sizeof(union cfw_cmd)))
    +
    +/**
    + * CFW Image
    + *
    + * A downloadable image
    + */
    +struct cfw_image {
    +	char name[CFW_MAX_ID];	/**< Name of the pfw/overlay/configuration*/
    +	char *desc;		/**< User string*/
    +	int mute_flags;
    +	struct cfw_block *block[CFW_BLOCK_N];
    +};
    +
    +
    +
    +/**
    + * CFW PLL
    + *
    + * PLL configuration sequence and match critirea
    + */
    +struct cfw_pll {
    +	char name[CFW_MAX_ID];	/**< Name of the PLL sequence*/
    +	char *desc;		/**< User string*/
    +	struct cfw_block *seq;
    +};
    +
    +/**
    + * CFW Control
    + *
    + * Run-time control for a process flow
    + */
    +struct cfw_control {
    +	char name[CFW_MAX_ID];	/**< Control identifier*/
    +	char *desc;		/**< User string*/
    +	int mute_flags;
    +
    +	int min;		/**< Min value of control (*100)*/
    +	int max;		/**< Max  value of control (*100)*/
    +	int step;		/**< Control step size (*100)*/
    +
    +	int imax;		/**< Max index into controls array*/
    +	int ireset;		/**< Reset control to defaults*/
    +	int icur;		/**< Last value set*/
    +	struct cfw_block **output;	/**< Array of sequences to send*/
    +};
    +
    +/**
    + * Process flow
    + *
    + * Complete description of a process flow
    + */
    +struct cfw_pfw {
    +	char name[CFW_MAX_ID];	/**< Name of the process flow*/
    +	char *desc;		/**< User string*/
    +	u32 version;
    +	u8 prb_a;
    +	u8 prb_d;
    +	int novly;		/**< Number of overlays (1 or more)*/
    +	int ncfg;		/**< Number of configurations (0 or more)*/
    +	int nctrl;		/**< Number of run-time controls*/
    +	struct cfw_image *base;	/**< Base sequence*/
    +	struct cfw_image **ovly_cfg;	/**< Overlay and cfg*/
    +					/**< patches (if any)*/
    +	struct cfw_control **ctrl;	/**< Array of run-time controls*/
    +};
    +
    +#define CFW_OCFG_NDX(p, o, c) (((o)*(p)->ncfg)+(c))
    +/**
    + * Process transition
    + *
    + * Sequence for specific state transisitions within the driver
    + *
    + */
    +struct cfw_transition {
    +	char name[CFW_MAX_ID];	/**< Name of the transition*/
    +	char *desc;		/**< User string*/
    +	struct cfw_block *block;
    +};
    +
    +/**
    + * Device audio mode
    + *
    + * Link operating modes to process flows,
    + * configurations and sequences
    + *
    + */
    +struct cfw_mode {
    +	char name[CFW_MAX_ID];
    +	char *desc;		/**< User string*/
    +	u32 flags;
    +	u8 pfw;
    +	u8 ovly;
    +	u8 cfg;
    +	u8 pll;
    +	struct cfw_block *entry;
    +	struct cfw_block *exit;
    +};
    +
    +struct cfw_asoc_toc_entry {
    +	char etext[CFW_MAX_ID];
    +	int mode;
    +	int cfg;
    +};
    +
    +struct cfw_asoc_toc {
    +	int nentries;
    +	struct cfw_asoc_toc_entry entry[];
    +};
    +
    +/**
    + * CFW Project
    + *
    + * Top level structure describing the CFW project
    + */
    +struct cfw_project {
    +	u32 magic;		/**< magic number for identifying F/W file*/
    +	u32 if_id;		/**< Interface match code */
    +	u32 size;		/**< Total size of the firmware (including this header)*/
    +	u32 cksum;		/**< CRC32 of the pickled firmware */
    +	u32 version;		/**< Firmware version (from CFD file)*/
    +	u32 tstamp;		/**< Time stamp of firmware build (epoch seconds)*/
    +	char name[CFW_MAX_ID];	/**< Project name*/
    +	char *desc;		/**< User string*/
    +	enum cfw_dfamily dfamily;	/**< Device family*/
    +	enum cfw_device device;	/**< Device identifier*/
    +	u32 flags;		/**< CFW flags*/
    +
    +	struct cfw_transition **transition;	/**< Transition sequences*/
    +
    +	u16 npll;		/**< Number of PLL settings*/
    +	struct cfw_pll **pll;	/**< PLL settings*/
    +
    +	u16 npfw;		/**< Number of process flows*/
    +	struct cfw_pfw **pfw;	/**< Process flows*/
    +
    +	u16 nmode;		/**< Number of operating modes*/
    +	struct cfw_mode **mode;	/**< Modes*/
    +
    +	struct cfw_asoc_toc *asoc_toc;	/**< list of amixer controls*/
    +};
    +
    +
    +/* @} */
    +
    +/* **CFW_INTERFACE_ID=0x3FA6D547** */
    +
    +#endif				/* CFW_FIRMWARE_H_ */
    diff --git a/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c b/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c
    new file mode 100644
    index 000000000..62b57870c
    --- /dev/null
    +++ b/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c
    @@ -0,0 +1,1134 @@
    +/*
    + * linux/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.c
    + *
    + * Copyright (C) 2011 Texas Instruments Inc.,
    + *
    + * This package is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2 as
    + * published by the Free Software Foundation.
    + *
    + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
    + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    + *
    + */
    +
    +#include <linux/module.h>
    +#include <linux/delay.h>
    +#include <sound/pcm.h>
    +#include <sound/pcm_params.h>
    +#include <sound/soc.h>
    +#include <linux/slab.h>
    +#include <sound/tlv.h>
    +
    +/* FIXME to be removed/replaced */
    +#define warn(fmt, ...)	printk(fmt "\n", ##__VA_ARGS__)
    +#define error(fmt, ...)	printk(fmt "\n", ##__VA_ARGS__)
    +#define DBG printk
    +
    +#include "aic3xxx_cfw.h"
    +#include "aic3xxx_cfw_ops.h"
    +
    +
    +/* **Code beyond this point is compilable on host** */
    +
    +/*
    + * Firmware version numbers are used to make sure that the
    + * host and target code stay in sync.  It is _not_ recommended
    + * to provide this number from the outside (E.g., from a makefile)
    + * Instead, a set of automated tools are relied upon to keep the numbers
    + * in sync at the time of host testing.
    + */
    +#undef CFW_FW_IF_ID
    +#define CFW_FW_IF_ID 0x3FA6D547
    +static int aic3xxx_cfw_dlimage(struct cfw_state *ps, struct cfw_image *pim);
    +static int aic3xxx_cfw_dlcfg(struct cfw_state *ps, struct cfw_image *pim);
    +static int aic3xxx_cfw_dlctl(struct cfw_state *ps, struct cfw_block *pb,
    +			     u32 mute_flags);
    +
    +static void aic3xxx_cfw_dlcmds(struct cfw_state *ps, struct cfw_block *pb);
    +static int aic3xxx_cfw_set_mode_id(struct cfw_state *ps);
    +static int aic3xxx_cfw_mute(struct cfw_state *ps, int mute, u32 flags);
    +static int aic3xxx_cfw_setmode_cfg_u(struct cfw_state *ps, int mode, int cfg);
    +static int aic3xxx_cfw_setcfg_u(struct cfw_state *ps, int cfg);
    +static int aic3xxx_cfw_transition_u(struct cfw_state *ps, char *ttype);
    +static int aic3xxx_cfw_set_pll_u(struct cfw_state *ps, int asi);
    +static int aic3xxx_cfw_control_u(struct cfw_state *ps, char *cname, int param);
    +static struct cfw_project *aic3xxx_cfw_unpickle(void *pcfw, int n);
    +
    +static void aic3xxx_wait(struct cfw_state *ps, unsigned int reg, u8 mask,
    +			 u8 data);
    +static void aic3xxx_set_bits(u8 *data, u8 mask, u8 val);
    +static int aic3xxx_driver_init(struct cfw_state *ps);
    +
    +int aic3xxx_cfw_init(struct cfw_state *ps, const struct aic3xxx_codec_ops *ops,
    +		     struct snd_soc_component *codec)
    +{
    +	ps->ops = ops;
    +	ps->codec = codec;
    +	ps->pjt = NULL;
    +	mutex_init(&ps->mutex);
    +
    +	/* FIXME Need a special CONFIG flag to disable debug driver */
    +	aic3xxx_driver_init(ps);
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_lock(struct cfw_state *ps, int lock)
    +{
    +	if (lock)
    +		mutex_lock(&ps->mutex);
    +	else
    +		mutex_unlock(&ps->mutex);
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_reload(struct cfw_state *ps, void *pcfw, int n)
    +{
    +	ps->pjt = aic3xxx_cfw_unpickle(pcfw, n);
    +	ps->cur_mode_id =
    +	    ps->cur_mode = ps->cur_pll = ps->cur_pfw =
    +	    ps->cur_ovly = ps->cur_cfg = -1;
    +	if (ps->pjt == NULL)
    +		return -1;
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_setmode(struct cfw_state *ps, int mode)
    +{
    +	struct cfw_project *pjt;
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	pjt = ps->pjt;
    +	if (pjt == NULL) {
    +		aic3xxx_cfw_lock(ps, 0);
    +		return -1;
    +	}
    +	ret = aic3xxx_cfw_setmode_cfg_u(ps, mode, pjt->mode[mode]->cfg);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +int aic3xxx_cfw_setcfg(struct cfw_state *ps, int cfg)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_setcfg_u(ps, cfg);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_setcfg_u(struct cfw_state *ps, int cfg)
    +{
    +	struct cfw_project *pjt = ps->pjt;
    +	struct cfw_pfw *pfw;
    +	struct cfw_image *patch;
    +
    +	if (pjt == NULL)
    +		return -1;
    +	if (ps->cur_pfw < 0 || ps->cur_pfw >= pjt->npfw)
    +		return -1;	/* Non miniDSP */
    +	if (ps->cur_cfg == cfg)
    +		return 0;
    +	pfw = pjt->pfw[ps->cur_pfw];
    +	if (pfw->ncfg == 0 && cfg != 0)
    +		return -1;
    +	if (cfg > 0 && cfg >= pfw->ncfg)
    +		return -1;
    +	ps->cur_cfg = cfg;
    +	aic3xxx_cfw_set_mode_id(ps);
    +	patch =
    +	    pfw->ovly_cfg[CFW_OCFG_NDX(pfw, ps->cur_ovly, ps->cur_cfg)];
    +	if (pfw->ncfg != 0)
    +		return aic3xxx_cfw_dlcfg(ps, patch);
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_setmode_cfg(struct cfw_state *ps, int mode, int cfg)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_setmode_cfg_u(ps, mode, cfg);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_setmode_cfg_u(struct cfw_state *ps, int mode, int cfg)
    +{
    +	struct cfw_project *pjt = ps->pjt;
    +	struct cfw_mode *pmode;
    +	int which = 0, ocndx;
    +
    +	if (pjt == NULL)
    +		goto err;
    +	if ((mode < 0) || (mode >= pjt->nmode))
    +		goto err;
    +	if (cfg < 0)
    +		goto err;
    +	if (mode == ps->cur_mode)
    +		return aic3xxx_cfw_setcfg_u(ps, cfg);
    +
    +	/* Apply exit sequence for previous mode if present */
    +	if (ps->cur_mode >= 0)
    +		aic3xxx_cfw_dlcmds(ps, pjt->mode[ps->cur_mode]->exit);
    +	pmode = pjt->mode[mode];
    +	if (pjt->mode[mode]->pfw < pjt->npfw) { /* New mode uses miniDSP */
    +		struct cfw_image *im;
    +		struct cfw_pfw *pfw = pjt->pfw[pmode->pfw];
    +
    +		/* Make sure cfg is valid and supported in this mode */
    +		if (pfw->ncfg == 0 && cfg != 0)
    +			goto err;
    +		if (cfg > 0 && cfg >= pfw->ncfg)
    +			goto err;
    +
    +		/*
    +		 * Decisions about which miniDSP to stop/restart are taken
    +		 * on the basis of sections present in the _base_ image
    +		 * This allows for correct sync mode operation even in cases
    +		 * where the base PFW uses both miniDSPs where a particular
    +		 * overlay applies only to one
    +		 */
    +		im = pfw->base;
    +		if (im->block[CFW_BLOCK_A_INST])
    +			which |= AIC3XXX_COPS_MDSP_A;
    +		if (im->block[CFW_BLOCK_D_INST])
    +			which |= AIC3XXX_COPS_MDSP_D;
    +
    +		if (pmode->pfw != ps->cur_pfw) {
    +
    +			/* New mode requires different PFW */
    +			ps->cur_pfw = pmode->pfw;
    +			ps->cur_ovly = 0;
    +			ps->cur_cfg = 0;
    +
    +			which = ps->ops->stop(ps->codec, which);
    +			aic3xxx_cfw_dlimage(ps, im);
    +			if (pmode->ovly && pmode->ovly < pfw->novly) {
    +
    +				/* New mode uses ovly */
    +				ocndx = CFW_OCFG_NDX(pfw, pmode->ovly, cfg);
    +				aic3xxx_cfw_dlimage(ps,
    +						    pfw->ovly_cfg[ocndx]);
    +			} else if (pfw->ncfg > 0) {
    +
    +				/* new mode needs only a cfg change */
    +				ocndx = CFW_OCFG_NDX(pfw, 0, cfg);
    +				aic3xxx_cfw_dlimage(ps,
    +						    pfw->ovly_cfg[ocndx]);
    +			}
    +			ps->ops->restore(ps->codec, which);
    +
    +		} else if (pmode->ovly != ps->cur_ovly) {
    +
    +			/* New mode requires only an ovly change */
    +			ocndx = CFW_OCFG_NDX(pfw, pmode->ovly, cfg);
    +			which = ps->ops->stop(ps->codec, which);
    +			aic3xxx_cfw_dlimage(ps, pfw->ovly_cfg[ocndx]);
    +			ps->ops->restore(ps->codec, which);
    +		} else if (pfw->ncfg > 0 && cfg != ps->cur_cfg) {
    +
    +			/* New mode requires only a cfg change */
    +			ocndx = CFW_OCFG_NDX(pfw, pmode->ovly, cfg);
    +			aic3xxx_cfw_dlcfg(ps, pfw->ovly_cfg[ocndx]);
    +		}
    +		ps->cur_ovly = pmode->ovly;
    +		ps->cur_cfg = cfg;
    +
    +		ps->cur_mode = mode;
    +		aic3xxx_cfw_set_pll_u(ps, 0);
    +
    +	} else if (pjt->mode[mode]->pfw != 0xFF) {
    +
    +		/* Not bypass mode */
    +		warn("Bad pfw setting detected (%d).  Max pfw=%d",
    +		     pmode->pfw, pjt->npfw);
    +	}
    +	ps->cur_mode = mode;
    +	aic3xxx_cfw_set_mode_id(ps);
    +
    +	/* Transition to netural mode */
    +	aic3xxx_cfw_transition_u(ps, "NEUTRAL");
    +
    +	/* Apply entry sequence if present */
    +	aic3xxx_cfw_dlcmds(ps, pmode->entry);
    +
    +	DBG("setmode_cfg: DONE (mode=%d pfw=%d ovly=%d cfg=%d)",
    +	    ps->cur_mode, ps->cur_pfw, ps->cur_ovly, ps->cur_cfg);
    +	return 0;
    +
    +err:
    +	DBG("Failed to set firmware mode");
    +	return -EINVAL;
    +}
    +
    +int aic3xxx_cfw_transition(struct cfw_state *ps, char *ttype)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_transition_u(ps, ttype);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_transition_u(struct cfw_state *ps, char *ttype)
    +{
    +	int i;
    +
    +	if (ps->pjt == NULL)
    +		return -EINVAL;
    +	for (i = 0; i < CFW_TRN_N; ++i) {
    +		if (!strcasecmp(ttype, cfw_transition_id[i])) {
    +			struct cfw_transition *pt = ps->pjt->transition[i];
    +			DBG("Sending transition %s[%d]", ttype, i);
    +			if (pt)
    +				aic3xxx_cfw_dlcmds(ps, pt->block);
    +			return 0;
    +		}
    +	}
    +	warn("Transition %s not present or invalid", ttype);
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_set_pll(struct cfw_state *ps, int asi)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_set_pll_u(ps, asi);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_set_pll_u(struct cfw_state *ps, int asi)
    +{
    +	struct cfw_project *pjt = ps->pjt;
    +	int pll_id;
    +
    +	if (pjt == NULL)
    +		return -EINVAL;
    +	if (ps->cur_mode < 0)
    +		return -EINVAL;
    +	pll_id = pjt->mode[ps->cur_mode]->pll;
    +	if (ps->cur_pll != pll_id) {
    +		DBG("Re-configuring PLL: %s==>%d", pjt->pll[pll_id]->name,
    +		    pll_id);
    +		aic3xxx_cfw_dlcmds(ps, pjt->pll[pll_id]->seq);
    +		ps->cur_pll = pll_id;
    +	}
    +	return 0;
    +}
    +
    +int aic3xxx_cfw_control(struct cfw_state *ps, char *cname, int param)
    +{
    +	int ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	ret = aic3xxx_cfw_control_u(ps, cname, param);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +static int aic3xxx_cfw_control_u(struct cfw_state *ps, char *cname, int param)
    +{
    +	struct cfw_pfw *pfw;
    +	int i;
    +
    +	if (ps->cur_pfw < 0 || ps->cur_pfw >= ps->pjt->npfw) {
    +		warn("Not in MiniDSP mode");
    +		return 0;
    +	}
    +	pfw = ps->pjt->pfw[ps->cur_pfw];
    +	for (i = 0; i < pfw->nctrl; ++i) {
    +		struct cfw_control *pc = pfw->ctrl[i];
    +		if (strcasecmp(cname, pfw->ctrl[i]->name))
    +			continue;
    +		if (param < 0 || param > pc->imax) {
    +			warn("Parameter out of range\n");
    +			return -EINVAL;
    +		}
    +		DBG("Sending control %s[%d]", cname, param);
    +		pc->icur = param;
    +		aic3xxx_cfw_dlctl(ps, pc->output[param], pc->mute_flags);
    +		return 0;
    +	}
    +	warn("Control named %s not found in pfw %s", cname, pfw->name);
    +
    +	return -EINVAL;
    +}
    +
    +static void aic3xxx_cfw_op(struct cfw_state *ps, unsigned char *var,
    +			   struct cfw_cmd_op cmd)
    +{
    +	u32 op1, op2;
    +	u32 cid = cmd.cid;
    +
    +	op1 = cmd.op1;
    +	op2 = cmd.op2;
    +	if (cid & CFW_CMD_OP1_ID)
    +		op1 = var[op1];
    +	if (cid & CFW_CMD_OP2_ID)
    +		op2 = var[op2];
    +	cid &= ~(CFW_CMD_OP1_ID | CFW_CMD_OP2_ID);
    +
    +	switch (cid) {
    +	case CFW_CMD_OP_ADD:
    +		var[cmd.dst] = op1 + op2;
    +		break;
    +	case CFW_CMD_OP_SUB:
    +		var[cmd.dst] = op1 - op2;
    +		break;
    +	case CFW_CMD_OP_MUL:
    +		var[cmd.dst] = op1 * op2;
    +		break;
    +	case CFW_CMD_OP_DIV:
    +		var[cmd.dst] = op1 / op2;
    +		break;
    +	case CFW_CMD_OP_AND:
    +		var[cmd.dst] = op1 & op2;
    +		break;
    +	case CFW_CMD_OP_OR:
    +		var[cmd.dst] = op1 | op2;
    +		break;
    +	case CFW_CMD_OP_SHL:
    +		var[cmd.dst] = (op1 << op2);
    +		break;
    +	case CFW_CMD_OP_SHR:
    +		var[cmd.dst] = (op1 >> op2);
    +		break;
    +	case CFW_CMD_OP_RR:
    +		while (op2--)
    +			var[cmd.dst] = (op1 >> 1) | ((op1 & 1) << 7);
    +		break;
    +	case CFW_CMD_OP_XOR:
    +		var[cmd.dst] = op1 ^ op2;
    +		break;
    +	case CFW_CMD_OP_NOT:
    +		var[cmd.dst] = ~op1;
    +		break;
    +	case CFW_CMD_OP_LNOT:
    +		var[cmd.dst] = !op1;
    +		break;
    +	default:
    +		break;
    +	}
    +}
    +
    +static void aic3xxx_cfw_dlcmds(struct cfw_state *ps, struct cfw_block *pb)
    +{
    +	int pc = 0, cond = 0;
    +	unsigned char var[256];
    +
    +	if (!pb)
    +		return;
    +	while (pc < pb->ncmds) {
    +		union cfw_cmd *c = &(pb->cmd[pc]);
    +		if (c->cid != CFW_CMD_BRANCH_IM &&
    +		    c->cid != CFW_CMD_BRANCH_ID && c->cid != CFW_CMD_NOP)
    +			cond = 0;
    +		switch (c->cid) {
    +		case 0 ... (CFW_CMD_NOP - 1):
    +			ps->ops->reg_write(ps->codec, c->reg.bpod,
    +					   c->reg.data);
    +			pc += 1;
    +			break;
    +		case CFW_CMD_NOP:
    +			pc += 1;
    +			break;
    +		case CFW_CMD_DELAY:
    +			mdelay(c->delay.delay);
    +			pc += 1;
    +			break;
    +		case CFW_CMD_UPDTBITS:
    +			ps->ops->set_bits(ps->codec, c[1].reg.bpod,
    +					  c->bitop.mask, c[1].reg.data);
    +			pc += 2;
    +			break;
    +		case CFW_CMD_WAITBITS:
    +			aic3xxx_wait(ps, c[1].reg.bpod, c->bitop.mask,
    +				     c[1].reg.data);
    +			pc += 2;
    +			break;
    +		case CFW_CMD_LOCK:
    +			if (c->delay.delay)
    +				ps->ops->lock(ps->codec);
    +			else
    +				ps->ops->unlock(ps->codec);
    +			pc += 1;
    +			break;
    +		case CFW_CMD_BURST:
    +			ps->ops->bulk_write(ps->codec, c[1].reg.bpod,
    +					    c->bhdr.len, c[1].burst.data);
    +			pc += CFW_CMD_BURST_LEN(c->bhdr.len);
    +			break;
    +		case CFW_CMD_RBURST:
    +			ps->ops->bulk_read(ps->codec, c[1].reg.bpod,
    +					    c->bhdr.len, c[1].burst.data);
    +			pc += CFW_CMD_BURST_LEN(c->bhdr.len);
    +			break;
    +		case CFW_CMD_LOAD_VAR_IM:
    +			aic3xxx_set_bits(&var[c->ldst.dvar],
    +					 c->ldst.mask, c->ldst.svar);
    +			pc += 1;
    +			break;
    +		case CFW_CMD_LOAD_VAR_ID:
    +			if (c->ldst.svar != c->ldst.dvar) {
    +				aic3xxx_set_bits(&var[c->ldst.dvar],
    +						 c->ldst.mask,
    +						 var[c->ldst.svar]);
    +				pc += 1;
    +			} else {
    +				u8 data;
    +				data = ps->ops->reg_read(ps->codec,
    +							c[1].reg.bpod);
    +				aic3xxx_set_bits(&var[c->ldst.dvar],
    +						 c->ldst.mask, data);
    +				pc += 2;
    +			}
    +			break;
    +		case CFW_CMD_STORE_VAR:
    +			if (c->ldst.svar != c->ldst.dvar)
    +				ps->ops->set_bits(ps->codec,
    +						  c[1].reg.bpod,
    +						  var[c->ldst.dvar],
    +						  var[c->ldst.svar]);
    +			else
    +				ps->ops->set_bits(ps->codec,
    +						  c[1].reg.bpod,
    +						  c->ldst.mask,
    +						  var[c->ldst.svar]);
    +			pc += 2;
    +			break;
    +		case CFW_CMD_COND:
    +			cond = var[c->cond.svar] & c->cond.mask;
    +			pc += 1;
    +			break;
    +		case CFW_CMD_BRANCH:
    +			pc = c->branch.address;
    +			break;
    +		case CFW_CMD_BRANCH_IM:
    +			if (c->branch.match == cond)
    +				pc = c->branch.address;
    +			else
    +				pc += 1;
    +			break;
    +		case CFW_CMD_BRANCH_ID:
    +			if (var[c->branch.match] == cond)
    +				pc = c->branch.address;
    +			else
    +				pc += 1;
    +			break;
    +		case CFW_CMD_PRINT:
    +			{
    +				union cfw_cmd *parglist =
    +				    c + CFW_CMD_PRINT_ARG(c->print);
    +				printk(c->print.fmt,
    +				     var[parglist->print_arg[0]],
    +				     var[parglist->print_arg[1]],
    +				     var[parglist->print_arg[2]],
    +				     var[parglist->print_arg[3]]);
    +				pc += CFW_CMD_PRINT_LEN(c->print);
    +			}
    +			break;
    +		case CFW_CMD_OP_START ... CFW_CMD_OP_END:
    +			aic3xxx_cfw_op(ps, var, c->op);
    +			pc += 1;
    +			break;
    +		default:
    +			warn("Unknown cmd command %x. Skipped", c->cid);
    +			pc += 1;
    +			break;
    +		}
    +	}
    +}
    +
    +static void aic3xxx_wait(struct cfw_state *ps, unsigned int reg, u8 mask,
    +			 u8 data)
    +{
    +	while ((ps->ops->reg_read(ps->codec, reg) & mask) != data)
    +		mdelay(2);
    +}
    +
    +static void aic3xxx_set_bits(u8 *data, u8 mask, u8 val)
    +{
    +	*data = (*data & (~mask)) | (val & mask);
    +}
    +
    +static const struct {
    +	u32 mdsp;
    +	int buf_a, buf_b;
    +	u32 swap;
    +} csecs[] = {
    +	{
    +		.mdsp = AIC3XXX_COPS_MDSP_A,
    +		.swap = AIC3XXX_ABUF_MDSP_A,
    +		.buf_a = CFW_BLOCK_A_A_COEF,
    +		.buf_b = CFW_BLOCK_A_B_COEF
    +	},
    +	{
    +		.mdsp = AIC3XXX_COPS_MDSP_D,
    +		.swap = AIC3XXX_ABUF_MDSP_D1,
    +		.buf_a = CFW_BLOCK_D_A1_COEF,
    +		.buf_b = CFW_BLOCK_D_B1_COEF
    +	},
    +	{
    +		.mdsp = AIC3XXX_COPS_MDSP_D,
    +		.swap = AIC3XXX_ABUF_MDSP_D2,
    +		.buf_a = CFW_BLOCK_D_A2_COEF,
    +		.buf_b = CFW_BLOCK_D_B2_COEF
    +	},
    +};
    +static int aic3xxx_cfw_dlctl(struct cfw_state *ps, struct cfw_block *pb,
    +			     u32 mute_flags)
    +{
    +	int i, btype = pb->type;
    +	int run_state = ps->ops->lock(ps->codec);
    +
    +	DBG("Download CTL");
    +	for (i = 0; i < sizeof(csecs) / sizeof(csecs[0]); ++i) {
    +		if (csecs[i].buf_a != btype && csecs[i].buf_b != btype)
    +			continue;
    +		DBG("\tDownload once to %d", btype);
    +		aic3xxx_cfw_dlcmds(ps, pb);
    +		if (run_state & csecs[i].mdsp) {
    +			DBG("\tDownload again to make sure it reaches B");
    +			aic3xxx_cfw_mute(ps, 1, run_state & mute_flags);
    +			ps->ops->bswap(ps->codec, csecs[i].swap);
    +			aic3xxx_cfw_mute(ps, 0, run_state & mute_flags);
    +			aic3xxx_cfw_dlcmds(ps, pb);
    +		}
    +		break;
    +	}
    +	ps->ops->unlock(ps->codec);
    +	return 0;
    +}
    +
    +static int aic3xxx_cfw_dlcfg(struct cfw_state *ps, struct cfw_image *pim)
    +{
    +	int i, run_state, swap;
    +
    +	DBG("Download CFG %s", pim->name);
    +	run_state = ps->ops->lock(ps->codec);
    +	swap = 0;
    +	for (i = 0; i < sizeof(csecs) / sizeof(csecs[0]); ++i) {
    +		if (!pim->block[csecs[i].buf_a])
    +			continue;
    +		aic3xxx_cfw_dlcmds(ps, pim->block[csecs[i].buf_a]);
    +		aic3xxx_cfw_dlcmds(ps, pim->block[csecs[i].buf_b]);
    +		if (run_state & csecs[i].mdsp)
    +			swap |= csecs[i].swap;
    +	}
    +	if (swap) {
    +		aic3xxx_cfw_mute(ps, 1, run_state & pim->mute_flags);
    +		ps->ops->bswap(ps->codec, swap);
    +		aic3xxx_cfw_mute(ps, 0, run_state & pim->mute_flags);
    +		for (i = 0; i < sizeof(csecs) / sizeof(csecs[0]); ++i) {
    +			if (!pim->block[csecs[i].buf_a])
    +				continue;
    +			if (!(run_state & csecs[i].mdsp))
    +				continue;
    +			aic3xxx_cfw_dlcmds(ps, pim->block[csecs[i].buf_a]);
    +			aic3xxx_cfw_dlcmds(ps, pim->block[csecs[i].buf_b]);
    +		}
    +	}
    +	ps->ops->unlock(ps->codec);
    +	return 0;
    +}
    +
    +static int aic3xxx_cfw_dlimage(struct cfw_state *ps, struct cfw_image *pim)
    +{
    +	int i;
    +
    +	if (!pim)
    +		return 0;
    +	DBG("Download IMAGE %s", pim->name);
    +	for (i = 0; i < CFW_BLOCK_N; ++i)
    +		aic3xxx_cfw_dlcmds(ps, pim->block[i]);
    +	return 0;
    +}
    +
    +static int aic3xxx_cfw_mute(struct cfw_state *ps, int mute, u32 flags)
    +{
    +	if ((flags & AIC3XXX_COPS_MDSP_D) && (flags & AIC3XXX_COPS_MDSP_A))
    +		aic3xxx_cfw_transition_u(ps,
    +					 mute ? "AD_MUTE" : "AD_UNMUTE");
    +	else if (flags & AIC3XXX_COPS_MDSP_D)
    +		aic3xxx_cfw_transition_u(ps, mute ? "D_MUTE" : "D_UNMUTE");
    +	else if (flags & AIC3XXX_COPS_MDSP_A)
    +		aic3xxx_cfw_transition_u(ps, mute ? "A_MUTE" : "A_UNMUTE");
    +	return 0;
    +}
    +
    +static inline void *aic3xxx_cfw_ndx2ptr(void *p, u8 *base)
    +{
    +	return &base[(int)p];
    +}
    +static inline char *aic3xxx_cfw_desc(void *p, u8 *base)
    +{
    +	if (p)
    +		return aic3xxx_cfw_ndx2ptr(p, base);
    +	return NULL;
    +}
    +
    +static void aic3xxx_cfw_unpickle_image(struct cfw_image *im, void *p)
    +{
    +	int i;
    +
    +	im->desc = aic3xxx_cfw_desc(im->desc, p);
    +	for (i = 0; i < CFW_BLOCK_N; ++i)
    +		if (im->block[i])
    +			im->block[i] = aic3xxx_cfw_ndx2ptr(im->block[i], p);
    +}
    +
    +static void aic3xxx_cfw_unpickle_control(struct cfw_control *ct, void *p)
    +{
    +	int i;
    +
    +	ct->output = aic3xxx_cfw_ndx2ptr(ct->output, p);
    +	ct->desc = aic3xxx_cfw_desc(ct->desc, p);
    +	for (i = 0; i <= ct->imax; ++i)
    +		ct->output[i] = aic3xxx_cfw_ndx2ptr(ct->output[i], p);
    +}
    +
    +static unsigned int crc32(unsigned int *pdata, int n)
    +{
    +	u32 crc = 0, i, crc_poly = 0x04C11DB7;	/* CRC - 32 */
    +	u32 msb;
    +	u32 residue_value = 0;
    +	int bits;
    +
    +	for (i = 0; i < (n >> 2); i++) {
    +		bits = 32;
    +		while (--bits >= 0) {
    +			msb = crc & 0x80000000;
    +			crc = (crc << 1) ^ ((*pdata >> bits) & 1);
    +			if (msb)
    +				crc = crc ^ crc_poly;
    +		}
    +		pdata++;
    +	}
    +
    +	switch (n & 3) {
    +	case 0:
    +		break;
    +	case 1:
    +		residue_value = (*pdata & 0xFF);
    +		bits = 8;
    +		break;
    +	case 2:
    +		residue_value = (*pdata & 0xFFFF);
    +		bits = 16;
    +		break;
    +	case 3:
    +		residue_value = (*pdata & 0xFFFFFF);
    +		bits = 24;
    +		break;
    +	}
    +
    +	if (n & 3) {
    +		while (--bits >= 0) {
    +			msb = crc & 0x80000000;
    +			crc = (crc << 1) ^ ((residue_value >> bits) & 1);
    +			if (msb)
    +				crc = crc ^ crc_poly;
    +		}
    +	}
    +	return crc;
    +}
    +
    +static int crc_chk(void *p, int n)
    +{
    +	struct cfw_project *pjt = (void *) p;
    +	u32 crc = pjt->cksum, crc_comp;
    +
    +	pjt->cksum = 0;
    +	DBG("Entering crc %d", n);
    +	crc_comp = crc32(p, n);
    +	if (crc_comp != crc) {
    +		DBG("CRC mismatch 0x%08X != 0x%08X", crc, crc_comp);
    +		return 0;
    +	}
    +	DBG("CRC pass");
    +	pjt->cksum = crc;
    +	return 1;
    +}
    +
    +static struct cfw_project *aic3xxx_cfw_unpickle(void *p, int n)
    +{
    +	struct cfw_project *pjt = p;
    +	int i, j;
    +
    +	if (pjt->magic != CFW_FW_MAGIC || pjt->size != n ||
    +	    pjt->if_id != CFW_FW_IF_ID || !crc_chk(p, n)) {
    +		error("Version mismatch: unable to load firmware\n");
    +		return NULL;
    +	}
    +	DBG("Loaded firmware inside unpickle\n");
    +
    +	pjt->desc = aic3xxx_cfw_desc(pjt->desc, p);
    +	pjt->transition = aic3xxx_cfw_ndx2ptr(pjt->transition, p);
    +	for (i = 0; i < CFW_TRN_N; i++) {
    +		if (!pjt->transition[i])
    +			continue;
    +		pjt->transition[i] = aic3xxx_cfw_ndx2ptr(pjt->transition[i], p);
    +		pjt->transition[i]->desc = aic3xxx_cfw_desc(
    +						pjt->transition[i]->desc, p);
    +		pjt->transition[i]->block = aic3xxx_cfw_ndx2ptr(
    +						pjt->transition[i]->block, p);
    +	}
    +	pjt->pll = aic3xxx_cfw_ndx2ptr(pjt->pll, p);
    +	for (i = 0; i < pjt->npll; i++) {
    +		pjt->pll[i] = aic3xxx_cfw_ndx2ptr(pjt->pll[i], p);
    +		pjt->pll[i]->desc = aic3xxx_cfw_desc(pjt->pll[i]->desc, p);
    +		pjt->pll[i]->seq = aic3xxx_cfw_ndx2ptr(pjt->pll[i]->seq, p);
    +	}
    +
    +	pjt->pfw = aic3xxx_cfw_ndx2ptr(pjt->pfw, p);
    +	for (i = 0; i < pjt->npfw; i++) {
    +		DBG("loading pfw %d\n", i);
    +		pjt->pfw[i] = aic3xxx_cfw_ndx2ptr(pjt->pfw[i], p);
    +		pjt->pfw[i]->desc = aic3xxx_cfw_desc(pjt->pfw[i]->desc, p);
    +		if (pjt->pfw[i]->base) {
    +			pjt->pfw[i]->base = aic3xxx_cfw_ndx2ptr(
    +							pjt->pfw[i]->base, p);
    +			aic3xxx_cfw_unpickle_image(pjt->pfw[i]->base, p);
    +		}
    +		pjt->pfw[i]->ovly_cfg = aic3xxx_cfw_ndx2ptr(
    +						pjt->pfw[i]->ovly_cfg, p);
    +		for (j = 0; j < pjt->pfw[i]->novly * pjt->pfw[i]->ncfg; ++j) {
    +			pjt->pfw[i]->ovly_cfg[j] = aic3xxx_cfw_ndx2ptr(
    +						pjt->pfw[i]->ovly_cfg[j], p);
    +			aic3xxx_cfw_unpickle_image(pjt->pfw[i]->ovly_cfg[j], p);
    +		}
    +		if (pjt->pfw[i]->nctrl)
    +			pjt->pfw[i]->ctrl = aic3xxx_cfw_ndx2ptr(
    +							pjt->pfw[i]->ctrl, p);
    +		for (j = 0; j < pjt->pfw[i]->nctrl; ++j) {
    +			pjt->pfw[i]->ctrl[j] = aic3xxx_cfw_ndx2ptr(
    +						pjt->pfw[i]->ctrl[j], p);
    +			aic3xxx_cfw_unpickle_control(pjt->pfw[i]->ctrl[j], p);
    +		}
    +	}
    +
    +	DBG("loaded pfw's\n");
    +	pjt->mode = aic3xxx_cfw_ndx2ptr(pjt->mode, p);
    +	for (i = 0; i < pjt->nmode; i++) {
    +		pjt->mode[i] = aic3xxx_cfw_ndx2ptr(pjt->mode[i], p);
    +		pjt->mode[i]->desc = aic3xxx_cfw_desc(pjt->mode[i]->desc, p);
    +		if (pjt->mode[i]->entry)
    +			pjt->mode[i]->entry = aic3xxx_cfw_ndx2ptr(
    +						pjt->mode[i]->entry, p);
    +		if (pjt->mode[i]->exit)
    +			pjt->mode[i]->exit = aic3xxx_cfw_ndx2ptr(
    +						pjt->mode[i]->exit, p);
    +	}
    +	if (pjt->asoc_toc)
    +		pjt->asoc_toc = aic3xxx_cfw_ndx2ptr(pjt->asoc_toc, p);
    +	else {
    +		warn("asoc_toc not defined.  FW version mismatch?");
    +		return NULL;
    +	}
    +	DBG("loaded modes");
    +	return pjt;
    +}
    +static int aic3xxx_cfw_set_mode_id(struct cfw_state *ps)
    +{
    +	struct cfw_asoc_toc *toc = ps->pjt->asoc_toc;
    +	int i;
    +
    +	for (i = 0; i < toc->nentries; ++i) {
    +		if (toc->entry[i].cfg == ps->cur_cfg &&
    +		    toc->entry[i].mode == ps->cur_mode) {
    +			ps->cur_mode_id = i;
    +			return 0;
    +		}
    +	}
    +	DBG("Unknown mode,cfg combination [%d,%d]", ps->cur_mode,
    +	    ps->cur_cfg);
    +	return -1;
    +}
    +
    +/* **Code beyond this point is not compilable on host** */
    +
    +static int aic3xxx_get_control(struct snd_kcontrol *kcontrol,
    +			       struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct cfw_state *ps = (struct cfw_state *)kcontrol->private_value;
    +	struct cfw_pfw *pfw;
    +	int i;
    +
    +	if (ps->cur_pfw >= ps->pjt->npfw) {
    +		DBG("Not in MiniDSP mode");
    +		return 0;
    +	}
    +	pfw = ps->pjt->pfw[ps->cur_pfw];
    +	for (i = 0; i < pfw->nctrl; ++i) {
    +		if (!strcasecmp(kcontrol->id.name, pfw->ctrl[i]->name)) {
    +			struct cfw_control *pc = pfw->ctrl[i];
    +			ucontrol->value.integer.value[0] = pc->icur;
    +			return 0;
    +		}
    +	}
    +	return 0;
    +}
    +
    +static int aic3xxx_put_control(struct snd_kcontrol *kcontrol,
    +			       struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct cfw_state *ps = (struct cfw_state *)kcontrol->private_value;
    +
    +	aic3xxx_cfw_control(ps, kcontrol->id.name,
    +			    ucontrol->value.integer.value[0]);
    +	return 0;
    +}
    +
    +static int aic3xxx_info_control(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_info *ucontrol)
    +{
    +	struct cfw_state *ps = (struct cfw_state *)kcontrol->private_value;
    +	struct cfw_pfw *pfw;
    +	int i;
    +
    +	if (ps->cur_pfw >= ps->pjt->npfw) {
    +		DBG("Not in MiniDSP mode");
    +		return 0;
    +	}
    +	pfw = ps->pjt->pfw[ps->cur_pfw];
    +	for (i = 0; i < pfw->nctrl; ++i) {
    +		if (!strcasecmp(kcontrol->id.name, pfw->ctrl[i]->name)) {
    +			struct cfw_control *pc = pfw->ctrl[i];
    +			ucontrol->value.integer.min = 0;
    +			ucontrol->value.integer.max = pc->imax;
    +			if (pc->imax == 1)
    +				ucontrol->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
    +			else
    +				ucontrol->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
    +		}
    +	}
    +
    +	ucontrol->count = 1;
    +	return 0;
    +}
    +int aic3xxx_cfw_add_controls(struct snd_soc_component *codec, struct cfw_state *ps)
    +{
    +	int i, j;
    +	struct cfw_pfw *pfw;
    +
    +	for (j = 0; j < ps->pjt->npfw; ++j) {
    +		pfw = ps->pjt->pfw[j];
    +
    +		for (i = 0; i < pfw->nctrl; ++i) {
    +			struct cfw_control *pc = pfw->ctrl[i];
    +			struct snd_kcontrol_new *generic_control =
    +			    kzalloc(sizeof(struct snd_kcontrol_new),
    +				    GFP_KERNEL);
    +			unsigned int *tlv_array =
    +			    kzalloc(4 * sizeof(unsigned int), GFP_KERNEL);
    +
    +			if (generic_control == NULL)
    +				return -ENOMEM;
    +			generic_control->access =
    +			    SNDRV_CTL_ELEM_ACCESS_TLV_READ |
    +			    SNDRV_CTL_ELEM_ACCESS_READWRITE;
    +			tlv_array[0] = SNDRV_CTL_TLVT_DB_SCALE;
    +			tlv_array[1] = 2 * sizeof(unsigned int);
    +			tlv_array[2] = pc->min;
    +			tlv_array[3] = ((pc->step) & TLV_DB_SCALE_MASK);
    +			if (pc->step > 0)
    +				generic_control->tlv.p = tlv_array;
    +			generic_control->name = pc->name;
    +			generic_control->private_value = (unsigned long) ps;
    +			generic_control->get = aic3xxx_get_control;
    +			generic_control->put = aic3xxx_put_control;
    +			generic_control->info = aic3xxx_info_control;
    +			generic_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
    +			snd_soc_add_component_controls(codec, generic_control, 1);
    +			DBG("Added control %s", pc->name);
    +		}
    +	}
    +	return 0;
    +
    +}
    +
    +
    +static int aic3xxx_get_mode(struct snd_kcontrol *kcontrol,
    +			    struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
    +	struct cfw_state *ps = (struct cfw_state *) e->mask;
    +
    +	ucontrol->value.enumerated.item[0] = ps->cur_mode_id;
    +
    +	return 0;
    +}
    +
    +static int aic3xxx_put_mode(struct snd_kcontrol *kcontrol,
    +			    struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct soc_enum *e = (struct soc_enum *) kcontrol->private_value;
    +	struct cfw_state *ps = (struct cfw_state *) e->mask;
    +	struct cfw_asoc_toc *toc;
    +	int index, ret;
    +
    +	aic3xxx_cfw_lock(ps, 1);
    +	toc = ps->pjt->asoc_toc;
    +
    +	index = ucontrol->value.enumerated.item[0];
    +	if (index < 0 || index >= toc->nentries) {
    +		aic3xxx_cfw_lock(ps, 0);
    +		return -EINVAL;
    +	}
    +	ret = aic3xxx_cfw_setmode_cfg_u(ps, toc->entry[index].mode,
    +				      toc->entry[index].cfg);
    +	aic3xxx_cfw_lock(ps, 0);
    +	return ret;
    +}
    +
    +int aic3xxx_cfw_add_modes(struct snd_soc_component *codec, struct cfw_state *ps)
    +{
    +	int j;
    +	struct cfw_asoc_toc *toc = ps->pjt->asoc_toc;
    +	struct soc_enum *mode_cfg_enum =
    +	    kzalloc(sizeof(struct soc_enum), GFP_KERNEL);
    +	struct snd_kcontrol_new *mode_cfg_control =
    +	    kzalloc(sizeof(struct snd_kcontrol_new), GFP_KERNEL);
    +	char **enum_texts;
    +
    +	if (mode_cfg_enum == NULL)
    +		goto mem_err;
    +	if (mode_cfg_control == NULL)
    +		goto mem_err;
    +
    +	mode_cfg_enum->texts = kzalloc(toc->nentries * sizeof(char *),
    +								GFP_KERNEL);
    +	if (mode_cfg_enum->texts == NULL)
    +		goto mem_err;
    +	/* Hack to overwrite the const * const pointer */
    +	enum_texts = (char **) mode_cfg_enum->texts;
    +
    +	for (j = 0; j < toc->nentries; j++)
    +		enum_texts[j] = toc->entry[j].etext;
    +
    +	mode_cfg_enum->reg = j;
    +	/* mode_cfg_enum->max = toc->nentries; */
    +	mode_cfg_enum->mask = (unsigned int) ps;
    +	mode_cfg_control->name = "Codec Firmware Setmode";
    +	mode_cfg_control->get = aic3xxx_get_mode;
    +	mode_cfg_control->put = aic3xxx_put_mode;
    +	/*mode_cfg_control->info = snd_soc_info_enum_ext;*/
    +	mode_cfg_control->private_value = (unsigned long) mode_cfg_enum;
    +	mode_cfg_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
    +	snd_soc_add_component_controls(codec, mode_cfg_control, 1);
    +	return 0;
    +mem_err:
    +	kfree(mode_cfg_control);
    +	kfree(mode_cfg_enum);
    +	kfree(mode_cfg_enum->texts);
    +	return -ENOMEM;
    +
    +}
    +
    +#if defined(CONFIG_AIC3111_CODEC) || defined(CONFIG_AIC3111_CORE)
    +
    +#	define AIC3XXX_CFW_DEVICE "aic3111_cfw"
    +#elif defined(CONFIG_AIC3256_CODEC) || defined(CONFIG_AIC3256_CORE)
    +
    +#	define AIC3XXX_CFW_DEVICE "aic3256_cfw"
    +#elif defined(CONFIG_AIC3262_CODEC) || defined(CONFIG_AIC3262_CORE)
    +#	define AIC3XXX_CFW_DEVICE "aic3262_cfw"
    +#else
    +#	define AIC3XXX_CFW_DEVICE "aic3xxx_cfw"
    +#endif
    +
    +static int aic3xxx_cfw_open(struct inode *in, struct file *filp)
    +{
    +	struct cfw_state *ps = container_of(in->i_cdev, struct cfw_state, cdev);
    +	if (ps->is_open) {
    +		warn("driver_open: device is already open");
    +		return -1;
    +	}
    +	ps->is_open++;
    +	filp->private_data = ps;
    +	return 0;
    +}
    +static int aic3xxx_cfw_release(struct inode *in, struct file *filp)
    +{
    +	struct cfw_state *ps = filp->private_data;
    +	ps->is_open--;
    +	return ps->is_open;
    +}
    +static long aic3xxx_cfw_ioctl(struct file *filp,
    +			unsigned int cmd, unsigned long arg)
    +{
    +	return 0;
    +}
    +static ssize_t aic3xxx_cfw_rw(struct file *filp, char __user *buf,
    +			   size_t count, loff_t *offset)
    +{
    +	struct cfw_state *ps = filp->private_data;
    +	struct cfw_block *kbuf = kmalloc(count, GFP_KERNEL);
    +	if (!kbuf || copy_from_user(kbuf, buf, count)) {
    +		warn("dev_rw: Allocation or copy failure");
    +		goto err;
    +	}
    +	if (count != CFW_BLOCK_SIZE(kbuf->ncmds)) {
    +		warn("dev_rw: Bad packet received\n");
    +		goto err;
    +	}
    +	aic3xxx_cfw_dlcmds(ps, kbuf);
    +	if (copy_to_user(buf, kbuf, count)) {
    +		warn("dev_rw: copy failure");
    +		goto err;
    +	}
    +	kfree(kbuf);
    +	return count;
    +err:
    +	kfree(kbuf);
    +	return -EINVAL;
    +}
    +
    +static const struct file_operations aic3xxx_cfw_fops = {
    +	.owner = THIS_MODULE,
    +	.open = aic3xxx_cfw_open,
    +	.release = aic3xxx_cfw_release,
    +	.read = aic3xxx_cfw_rw,
    +	.write = (ssize_t (*)(struct file *filp, const char __user *buf,
    +			size_t count, loff_t *offset))aic3xxx_cfw_rw,
    +	.unlocked_ioctl = aic3xxx_cfw_ioctl,
    +};
    +static int aic3xxx_driver_init(struct cfw_state *ps)
    +{
    +	int err;
    +
    +	dev_t dev = MKDEV(0, 0);
    +
    +	err = alloc_chrdev_region(&dev, 0, 1, AIC3XXX_CFW_DEVICE);
    +	if (err < 0) {
    +		warn("driver_init: Error allocating device number");
    +		return err;
    +	}
    +	warn("driver_init: Allocated Major Number: %d\n", MAJOR(dev));
    +
    +	cdev_init(&(ps->cdev), &aic3xxx_cfw_fops);
    +	ps->cdev.owner = THIS_MODULE;
    +	ps->cdev.ops = &aic3xxx_cfw_fops;
    +	ps->is_open = 0;
    +
    +	err = cdev_add(&(ps->cdev), dev, 1);
    +	if (err < 0) {
    +		warn("driver_init: cdev_add failed");
    +		unregister_chrdev_region(dev, 1);
    +		return err;
    +	}
    +	warn("driver_init: Registered cfw driver");
    +	return 0;
    +}
    +
    +MODULE_DESCRIPTION("ASoC tlv320aic3xxx codec driver firmware functions");
    +MODULE_AUTHOR("Hari Rajagopala <harik@ti.com>");
    +MODULE_LICENSE("GPL");
    +
    diff --git a/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h b/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h
    new file mode 100644
    index 000000000..c58613359
    --- /dev/null
    +++ b/sound/soc/codecs/aic3xxx/aic3xxx_cfw_ops.h
    @@ -0,0 +1,95 @@
    +/*
    + * aic3xxx_cfw_ops.h  --  SoC audio for TI OMAP44XX SDP
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * version 2 as published by the Free Software Foundation.
    + *
    + * 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 St, Fifth Floor, Boston, MA
    + * 02110-1301 USA
    + *
    + */
    +
    +#ifndef AIC3XXX_CFW_OPS_H_
    +#define AIC3XXX_CFW_OPS_H_
    +
    +#include <linux/mutex.h>
    +#include <sound/soc.h>
    +#include <linux/cdev.h>
    +
    +struct cfw_project;
    +struct aic3xxx_codec_ops;
    +
    +struct cfw_state {
    +	struct cfw_project *pjt;
    +	const struct aic3xxx_codec_ops  *ops;
    +	struct snd_soc_component *codec;
    +	struct mutex mutex;
    +	int cur_mode_id;
    +	int cur_pll;
    +	int cur_mode;
    +	int cur_pfw;
    +	int cur_ovly;
    +	int cur_cfg;
    +	struct cdev cdev;
    +	int is_open;
    +};
    +
    +int aic3xxx_cfw_init(struct cfw_state *ps, const struct aic3xxx_codec_ops *ops,
    +		     struct snd_soc_component *codec);
    +int aic3xxx_cfw_lock(struct cfw_state *ps, int lock);
    +int aic3xxx_cfw_reload(struct cfw_state *ps, void *pcfw, int n);
    +int aic3xxx_cfw_setmode(struct cfw_state *ps, int mode);
    +int aic3xxx_cfw_setmode_cfg(struct cfw_state *ps, int mode, int cfg);
    +int aic3xxx_cfw_setcfg(struct cfw_state *ps, int cfg);
    +int aic3xxx_cfw_transition(struct cfw_state *ps, char *ttype);
    +int aic3xxx_cfw_set_pll(struct cfw_state *ps, int asi);
    +int aic3xxx_cfw_control(struct cfw_state *ps, char *cname, int param);
    +int aic3xxx_cfw_add_controls(struct snd_soc_component *codec, struct cfw_state *ps);
    +int aic3xxx_cfw_add_modes(struct snd_soc_component *codec, struct cfw_state *ps);
    +
    +
    +#define AIC3XXX_COPS_MDSP_D_L    (0x00000002u)
    +#define AIC3XXX_COPS_MDSP_D_R    (0x00000001u)
    +#define AIC3XXX_COPS_MDSP_D      (AIC3XXX_COPS_MDSP_D_L|AIC3XXX_COPS_MDSP_D_R)
    +
    +#define AIC3XXX_COPS_MDSP_A_L    (0x00000020u)
    +#define AIC3XXX_COPS_MDSP_A_R    (0x00000010u)
    +#define AIC3XXX_COPS_MDSP_A      (AIC3XXX_COPS_MDSP_A_L|AIC3XXX_COPS_MDSP_A_R)
    +
    +#define AIC3XXX_COPS_MDSP_ALL    (AIC3XXX_COPS_MDSP_D|AIC3XXX_COPS_MDSP_A)
    +
    +#define AIC3XXX_ABUF_MDSP_D1 (0x00000001u)
    +#define AIC3XXX_ABUF_MDSP_D2 (0x00000002u)
    +#define AIC3XXX_ABUF_MDSP_A  (0x00000010u)
    +#define AIC3XXX_ABUF_MDSP_ALL \
    +		(AIC3XXX_ABUF_MDSP_D1|AIC3XXX_ABUF_MDSP_D2|AIC3XXX_ABUF_MDSP_A)
    +
    +
    +struct aic3xxx_codec_ops {
    +	int (*reg_read) (struct snd_soc_component *codec, unsigned int reg);
    +	int (*reg_write) (struct snd_soc_component *codec, unsigned int reg,
    +					unsigned char val);
    +	int (*set_bits) (struct snd_soc_component *codec, unsigned int reg,
    +					unsigned char mask, unsigned char val);
    +	int (*bulk_read) (struct snd_soc_component *codec, unsigned int reg,
    +					int count, u8 *buf);
    +	int (*bulk_write) (struct snd_soc_component *codec, unsigned int reg,
    +					int count, const u8 *buf);
    +	int (*lock) (struct snd_soc_component *codec);
    +	int (*unlock) (struct snd_soc_component *codec);
    +	int (*stop) (struct snd_soc_component *codec, int mask);
    +	int (*restore) (struct snd_soc_component *codec, int runstate);
    +	int (*bswap) (struct snd_soc_component *codec, int mask);
    +};
    +
    +MODULE_LICENSE("GPL");
    +
    +#endif
    diff --git a/sound/soc/codecs/tlv320aic326x.c b/sound/soc/codecs/tlv320aic326x.c
    new file mode 100644
    index 000000000..59199f33a
    --- /dev/null
    +++ b/sound/soc/codecs/tlv320aic326x.c
    @@ -0,0 +1,2641 @@
    +/*
    + * linux/sound/soc/codecs/tlv320aic326x.c
    + *
    + * Copyright (C) 2011 Texas Instruments Inc.,
    + *
    + * This package is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2 as
    + * published by the Free Software Foundation.
    + *
    + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
    + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    + *
    + * The TLV320AIC3262 is a flexible, low-power, low-voltage stereo audio
    + * codec with digital microphone inputs and programmable outputs.
    + *
    + * History:
    + *
    + * Rev 0.1   ASoC driver support    TI	20-01-2011
    + *
    + *		The AIC325x ASoC driver is ported for the codec AIC3262.
    + * Rev 0.2   ASoC driver support    TI	21-03-2011
    + *		The AIC326x ASoC driver is updated for linux 2.6.32 Kernel.
    + * Rev 0.3   ASoC driver support    TI	   20-04-2011
    + *		The AIC326x ASoC driver is ported to 2.6.35 omap4 kernel
    + */
    +
    +/*
    + *****************************************************************************
    + * INCLUDES
    + *****************************************************************************
    + */
    +
    +#include <linux/module.h>
    +#include <linux/moduleparam.h>
    +#include <linux/init.h>
    +#include <linux/delay.h>
    +#include <linux/pm.h>
    +#include <linux/i2c.h>
    +#include <linux/pm_runtime.h>
    +#include <linux/spi/spi.h>
    +#include <linux/platform_device.h>
    +#include <sound/jack.h>
    +#include <linux/irq.h>
    +#include <linux/interrupt.h>
    +#include <linux/cdev.h>
    +#include <linux/slab.h>
    +#include <linux/firmware.h>
    +#include <linux/input.h>
    +
    +#include <sound/tlv.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 <linux/mfd/tlv320aic3262-registers.h>
    +#include <linux/mfd/tlv320aic3xxx-core.h>
    +#include "aic3xxx/aic3xxx_cfw_ops.h"
    +
    +#include "tlv320aic326x.h"
    +
    +/*****************************************************************************
    +			 Macros
    +******************************************************************************
    +
    +******************************************************************************
    +		  Function Prototype
    +******************************************************************************/
    +
    +static int aic3262_hw_params(struct snd_pcm_substream *substream,
    +			     struct snd_pcm_hw_params *params,
    +			     struct snd_soc_dai *dai);
    +
    +static int aic3262_mute(struct snd_soc_dai *dai, int mute, int direction);
    +
    +static int aic3262_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt);
    +
    +static int aic3262_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
    +				unsigned int Fin, unsigned int Fout);
    +
    +static int aic3262_set_bias_level(struct snd_soc_component *codec,
    +				  enum snd_soc_bias_level level);
    +
    +static int aic3262_set_mode_get(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_value *ucontrol);
    +static int aic3262_set_mode_put(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_value *ucontrol);
    +
    +static int aic326x_adc_dsp_event(struct snd_soc_dapm_widget *w,
    +				 struct snd_kcontrol *kcontrol, int event);
    +static int aic3262_get_runstate(struct snd_soc_component *codec);
    +static int aic3262_dsp_pwrdwn_status(struct snd_soc_component *codec);
    +static int aic3262_dsp_pwrup(struct snd_soc_component *codec, int state);
    +static int aic3262_restart_dsps_sync(struct snd_soc_component *codec, int rs);
    +
    +static inline unsigned int dsp_non_sync_mode(unsigned int state)
    +			{ return (!((state & 0x03) && (state & 0x30))); }
    +
    +static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0);
    +static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1200, 50, 0);
    +static const DECLARE_TLV_DB_SCALE(spk_gain_tlv, 600, 600, 0);
    +static const DECLARE_TLV_DB_SCALE(output_gain_tlv, -600, 100, 1);
    +static const DECLARE_TLV_DB_SCALE(micpga_gain_tlv, 0, 50, 0);
    +static const DECLARE_TLV_DB_SCALE(adc_fine_gain_tlv, -40, 10, 0);
    +static const DECLARE_TLV_DB_SCALE(beep_gen_volume_tlv, -6300, 100, 0);
    +
    +/* Chip-level Input and Output CM Mode Controls */
    +static const char * const input_common_mode_text[] = {
    +	"0.9v", "0.75v"
    +};
    +
    +static const char * const output_common_mode_text[] = {
    +	"Input CM", "1.25v", "1.5v", "1.65v"
    +};
    +
    +static const struct soc_enum input_cm_mode =
    +SOC_ENUM_SINGLE(AIC3262_CM_REG, 2, 2, input_common_mode_text);
    +
    +static const struct soc_enum output_cm_mode =
    +SOC_ENUM_SINGLE(AIC3262_CM_REG, 0, 4, output_common_mode_text);
    +/*
    + *****************************************************************************
    + * Structure Initialization
    + *****************************************************************************
    + */
    +static const struct snd_kcontrol_new aic3262_snd_controls[] = {
    +	/* Output */
    +#ifndef DAC_INDEPENDENT_VOL
    +	/* sound new kcontrol for PCM Playback volume control */
    +
    +	SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
    +				AIC3262_DAC_LVOL, AIC3262_DAC_RVOL, 0,
    +				0x81, 0xaf, dac_vol_tlv),
    +#endif
    +	/*HP Driver Gain Control */
    +	SOC_DOUBLE_R_SX_TLV("HeadPhone Driver Amplifier Volume",
    +				AIC3262_HPL_VOL, AIC3262_HPR_VOL, 0, 0x39,
    +				0x15, output_gain_tlv),
    +	/*LO Driver Gain Control */
    +	SOC_DOUBLE_TLV("Speaker Amplifier Volume", AIC3262_SPK_AMP_CNTL_R4, 4,
    +			0, 5, 0, spk_gain_tlv),
    +
    +	SOC_DOUBLE_R_SX_TLV("Receiver Amplifier Volume",
    +				AIC3262_REC_AMP_CNTL_R5, AIC3262_RAMPR_VOL, 0,
    +				0x39, 0x24, output_gain_tlv),
    +
    +	SOC_DOUBLE_R_SX_TLV("PCM Capture Volume", AIC3262_LADC_VOL,
    +				AIC3262_RADC_VOL, 0, 0x68, 0x41,
    +				adc_vol_tlv),
    +
    +	SOC_DOUBLE_R_TLV("MicPGA Volume Control", AIC3262_MICL_PGA,
    +			 AIC3262_MICR_PGA, 0, 0x5F, 0, micpga_gain_tlv),
    +
    +	SOC_DOUBLE_TLV("PCM Capture Fine Gain Volume", AIC3262_ADC_FINE_GAIN,
    +			4, 0, 5, 1, adc_fine_gain_tlv),
    +
    +	SOC_DOUBLE("ADC channel mute", AIC3262_ADC_FINE_GAIN, 7, 3, 1, 0),
    +
    +	SOC_DOUBLE("DAC MUTE", AIC3262_DAC_MVOL_CONF, 2, 3, 1, 1),
    +
    +	SOC_SINGLE("RESET", AIC3262_RESET_REG, 0, 1, 0),
    +
    +	SOC_SINGLE("DAC VOL SOFT STEPPING", AIC3262_DAC_MVOL_CONF, 0, 2, 0),
    +
    +	SOC_SINGLE("DAC AUTO MUTE CONTROL", AIC3262_DAC_MVOL_CONF, 4, 7, 0),
    +
    +	SOC_SINGLE("RIGHT MODULATOR SETUP", AIC3262_DAC_MVOL_CONF, 7, 1, 0),
    +
    +	SOC_SINGLE("ADC Volume soft stepping", AIC3262_ADC_CHANNEL_POW,
    +		   0, 3, 0),
    +
    +	SOC_SINGLE("Mic Bias ext independent enable", AIC3262_MIC_BIAS_CNTL,
    +		   7, 1, 0),
    +
    +	SOC_SINGLE("MICBIAS EXT Power Level", AIC3262_MIC_BIAS_CNTL, 4, 3, 0),
    +
    +	SOC_SINGLE("MICBIAS INT Power Level", AIC3262_MIC_BIAS_CNTL, 0, 3, 0),
    +
    +	SOC_SINGLE("BEEP_GEN_EN", AIC3262_BEEP_CNTL_R1, 7, 1, 0),
    +
    +	SOC_DOUBLE_R("BEEP_VOL_CNTL", AIC3262_BEEP_CNTL_R1,
    +		     AIC3262_BEEP_CNTL_R2, 0, 0x0F, 1),
    +
    +	SOC_SINGLE("BEEP_MAS_VOL", AIC3262_BEEP_CNTL_R2, 6, 3, 0),
    +
    +	SOC_SINGLE("DAC PRB Selection", AIC3262_DAC_PRB, 0, 26, 0),
    +
    +	SOC_SINGLE("ADC PRB Selection", AIC3262_ADC_PRB, 0, 18, 0),
    +
    +	SOC_ENUM("Input CM mode", input_cm_mode),
    +
    +	SOC_ENUM("Output CM mode", output_cm_mode),
    +
    +	SOC_SINGLE_EXT("FIRMWARE SET MODE", SND_SOC_NOPM, 0, 0xffff, 0,
    +			aic3262_set_mode_get, aic3262_set_mode_put),
    +};
    +
    +/*
    + *----------------------------------------------------------------------------
    + * @struct  snd_soc_component_dai |
    + *	It is SoC Codec DAI structure which has DAI capabilities viz.,
    + *	playback and capture, DAI runtime information viz. state of DAI
    + *			and pop wait state, and DAI private data.
    + *	The AIC3262 rates ranges from 8k to 192k
    + *	The PCM bit format supported are 16, 20, 24 and 32 bits
    + *----------------------------------------------------------------------------
    + */
    +struct snd_soc_dai_ops aic3262_asi1_dai_ops = {
    +	.hw_params = aic3262_hw_params,
    +	.mute_stream = aic3262_mute,
    +	.set_fmt = aic3262_set_dai_fmt,
    +	.set_pll = aic3262_dai_set_pll,
    +};
    +
    +struct snd_soc_dai_ops aic3262_asi2_dai_ops = {
    +	.hw_params = aic3262_hw_params,
    +	.mute_stream = aic3262_mute,
    +	.set_fmt = aic3262_set_dai_fmt,
    +	.set_pll = aic3262_dai_set_pll,
    +};
    +
    +struct snd_soc_dai_ops aic3262_asi3_dai_ops = {
    +	.hw_params = aic3262_hw_params,
    +	.mute_stream = aic3262_mute,
    +	.set_fmt = aic3262_set_dai_fmt,
    +	.set_pll = aic3262_dai_set_pll,
    +};
    +
    +struct snd_soc_dai_driver aic326x_dai_driver[] = {
    +	{
    +	 .name = "aic326x-asi1",
    +	 .playback = {
    +		      .stream_name = "ASI1 Playback",
    +		      .channels_min = 1,
    +		      .channels_max = 8,
    +		      .rates = AIC3262_RATES,
    +		      .formats = AIC3262_FORMATS,
    +		      },
    +	 .capture = {
    +		     .stream_name = "ASI1 Capture",
    +		     .channels_min = 1,
    +		     .channels_max = 8,
    +		     .rates = AIC3262_RATES,
    +		     .formats = AIC3262_FORMATS,
    +		     },
    +	 .ops = &aic3262_asi1_dai_ops,
    +	 },
    +	{
    +	 .name = "aic326x-asi2",
    +	 .playback = {
    +		      .stream_name = "ASI2 Playback",
    +		      .channels_min = 1,
    +		      .channels_max = 2,
    +		      .rates = AIC3262_RATES,
    +		      .formats = AIC3262_FORMATS,
    +		      },
    +	 .capture = {
    +		     .stream_name = "ASI2 Capture",
    +		     .channels_min = 1,
    +		     .channels_max = 2,
    +		     .rates = AIC3262_RATES,
    +		     .formats = AIC3262_FORMATS,
    +		     },
    +	 .ops = &aic3262_asi2_dai_ops,
    +	 },
    +	{
    +	 .name = "aic326x-asi3",
    +	 .playback = {
    +		      .stream_name = "ASI3 Playback",
    +		      .channels_min = 1,
    +		      .channels_max = 2,
    +		      .rates = AIC3262_RATES,
    +		      .formats = AIC3262_FORMATS,
    +		      },
    +	 .capture = {
    +		     .stream_name = "ASI3 Capture",
    +		     .channels_min = 1,
    +		     .channels_max = 2,
    +		     .rates = AIC3262_RATES,
    +		     .formats = AIC3262_FORMATS,
    +		     },
    +	 .ops = &aic3262_asi3_dai_ops,
    +	 },
    +
    +};
    +
    +static const unsigned int adc_ma_tlv[] = {
    +	TLV_DB_RANGE_HEAD(7),
    +	1, 1, TLV_DB_SCALE_ITEM(-3610, 0, 0),
    +	2, 2, TLV_DB_SCALE_ITEM(-3010, 0, 0),
    +	3, 3, TLV_DB_SCALE_ITEM(-2660, 0, 0),
    +	4, 4, TLV_DB_SCALE_ITEM(-2410, 0, 0),
    +	5, 7, TLV_DB_SCALE_ITEM(-2210, 1500, 0),
    +	8, 11, TLV_DB_SCALE_ITEM(-1810, 1000, 0),
    +	12, 41 , TLV_DB_SCALE_ITEM(-1450, 500, 0)
    +};
    +
    +static const DECLARE_TLV_DB_SCALE(lo_hp_tlv, -7830, 50, 0);
    +static const struct snd_kcontrol_new mal_pga_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("IN1 Left Capture Switch", AIC3262_MA_CNTL, 5, 1, 0),
    +	SOC_DAPM_SINGLE_TLV("Left MicPGA Volume", AIC3262_LADC_PGA_MAL_VOL,
    +				0, 0x3f, 1, adc_ma_tlv),
    +};
    +
    +static const struct snd_kcontrol_new mar_pga_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("IN1 Right Capture Switch", AIC3262_MA_CNTL, 4, 1, 0),
    +	SOC_DAPM_SINGLE_TLV("Right MicPGA Volume", AIC3262_RADC_PGA_MAR_VOL,
    +				0, 0x3f, 1, adc_ma_tlv),
    +};
    +
    +/* Left HPL Mixer */
    +static const struct snd_kcontrol_new hpl_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("MA Left Playback Switch", AIC3262_HP_AMP_CNTL_R1, 7, 1,
    +			0),
    +	SOC_DAPM_SINGLE("Left DAC Playback Switch", AIC3262_HP_AMP_CNTL_R1,
    +			5, 1, 0),
    +	SOC_DAPM_SINGLE_TLV("LO Left-B1 Playback Volume",
    +				AIC3262_HP_AMP_CNTL_R2, 0, 0x7f, 1, lo_hp_tlv),
    +};
    +
    +/* Right HPR Mixer */
    +static const struct snd_kcontrol_new hpr_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE_TLV("LO Right-B1 Playback Volume",
    +				AIC3262_HP_AMP_CNTL_R3, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE("Left DAC Playback Switch", AIC3262_HP_AMP_CNTL_R1,
    +			2, 1, 0),
    +	SOC_DAPM_SINGLE("Right DAC Playback Switch", AIC3262_HP_AMP_CNTL_R1,
    +			4, 1, 0),
    +	SOC_DAPM_SINGLE("MA Right Playback Switch", AIC3262_HP_AMP_CNTL_R1,
    +			6, 1, 0),
    +};
    +
    +/* Left LOL Mixer */
    +static const struct snd_kcontrol_new lol_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("MA Left Playback Switch", AIC3262_LINE_AMP_CNTL_R2,
    +			7, 1, 0),
    +	SOC_DAPM_SINGLE("IN1 Left-B Capture Switch", AIC3262_LINE_AMP_CNTL_R2,
    +			3, 1, 0),
    +	SOC_DAPM_SINGLE("Left DAC Playback Switch", AIC3262_LINE_AMP_CNTL_R1,
    +			7, 1, 0),
    +	SOC_DAPM_SINGLE("Right DAC Playback Switch", AIC3262_LINE_AMP_CNTL_R1,
    +			5, 1, 0),
    +};
    +
    +/* Right LOR Mixer */
    +static const struct snd_kcontrol_new lor_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("LO Left Playback Switch", AIC3262_LINE_AMP_CNTL_R1,
    +			2, 1, 0),
    +	SOC_DAPM_SINGLE("Right DAC Playback Switch", AIC3262_LINE_AMP_CNTL_R1,
    +			6, 1, 0),
    +	SOC_DAPM_SINGLE("MA Right Playback Switch", AIC3262_LINE_AMP_CNTL_R2,
    +			6, 1, 0),
    +	SOC_DAPM_SINGLE("IN1 Right-B Capture Switch", AIC3262_LINE_AMP_CNTL_R2,
    +			0, 1, 0),
    +};
    +
    +/* Left SPKL Mixer */
    +static const struct snd_kcontrol_new spkl_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("MA Left Playback Switch", AIC3262_SPK_AMP_CNTL_R1,
    +			7, 1, 0),
    +	SOC_DAPM_SINGLE_TLV("LO Left Playback Volume",
    +				AIC3262_SPK_AMP_CNTL_R2, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE("SPR_IN Switch", AIC3262_SPK_AMP_CNTL_R1, 2, 1, 0),
    +};
    +
    +/* Right SPKR Mixer */
    +static const struct snd_kcontrol_new spkr_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE_TLV("LO Right Playback Volume",
    +				AIC3262_SPK_AMP_CNTL_R3, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE("MA Right Playback Switch",
    +			AIC3262_SPK_AMP_CNTL_R1, 6, 1, 0),
    +};
    +
    +/* REC Mixer */
    +static const struct snd_kcontrol_new rec_output_mixer_controls[] = {
    +	SOC_DAPM_SINGLE_TLV("LO Left-B2 Playback Volume",
    +				AIC3262_RAMP_CNTL_R1, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE_TLV("IN1 Left Capture Volume",
    +				AIC3262_IN1L_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE_TLV("IN1 Right Capture Volume",
    +				AIC3262_IN1R_SEL_RM, 0, 0x7f, 1, lo_hp_tlv),
    +	SOC_DAPM_SINGLE_TLV("LO Right-B2 Playback Volume",
    +				AIC3262_RAMP_CNTL_R2, 0, 0x7f, 1, lo_hp_tlv),
    +};
    +
    +/* Left Input Mixer */
    +static const struct snd_kcontrol_new left_input_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("IN1 Left Capture Switch", AIC3262_LMIC_PGA_PIN,
    +			6, 3, 0),
    +	SOC_DAPM_SINGLE("IN2 Left Capture Switch", AIC3262_LMIC_PGA_PIN,
    +			4, 3, 0),
    +	SOC_DAPM_SINGLE("IN3 Left Capture Switch", AIC3262_LMIC_PGA_PIN,
    +			2, 3, 0),
    +	SOC_DAPM_SINGLE("IN4 Left Capture Switch", AIC3262_LMIC_PGA_PM_IN4,
    +			5, 1, 0),
    +	SOC_DAPM_SINGLE("IN1 Right Capture Switch", AIC3262_LMIC_PGA_PIN,
    +			0, 3, 0),
    +	SOC_DAPM_SINGLE("IN2 Right Capture Switch", AIC3262_LMIC_PGA_MIN,
    +			4, 3, 0),
    +	SOC_DAPM_SINGLE("IN3 Right Capture Switch", AIC3262_LMIC_PGA_MIN,
    +			2, 3, 0),
    +	SOC_DAPM_SINGLE("IN4 Right Capture Switch", AIC3262_LMIC_PGA_PM_IN4,
    +			4, 1, 0),
    +	SOC_DAPM_SINGLE("CM2 Left Capture Switch", AIC3262_LMIC_PGA_MIN,
    +			0, 3, 0),
    +	SOC_DAPM_SINGLE("CM1 Left Capture Switch", AIC3262_LMIC_PGA_MIN,
    +			6, 3, 0),
    +};
    +
    +/* Right Input Mixer */
    +static const struct snd_kcontrol_new right_input_mixer_controls[] = {
    +	SOC_DAPM_SINGLE("IN1 Right Capture Switch", AIC3262_RMIC_PGA_PIN,
    +			6, 3, 0),
    +	SOC_DAPM_SINGLE("IN2 Right Capture Switch", AIC3262_RMIC_PGA_PIN,
    +			4, 3, 0),
    +	SOC_DAPM_SINGLE("IN3 Right Capture Switch", AIC3262_RMIC_PGA_PIN,
    +			2, 3, 0),
    +	SOC_DAPM_SINGLE("IN4 Right Capture Switch", AIC3262_RMIC_PGA_PM_IN4,
    +			5, 1, 0),
    +	SOC_DAPM_SINGLE("IN2 Left Capture Switch", AIC3262_RMIC_PGA_PIN,
    +			0, 3, 0),
    +	SOC_DAPM_SINGLE("IN1 Left Capture Switch", AIC3262_RMIC_PGA_MIN,
    +			4, 3, 0),
    +	SOC_DAPM_SINGLE("IN3 Left Capture Switch", AIC3262_RMIC_PGA_MIN,
    +			2, 3, 0),
    +	SOC_DAPM_SINGLE("IN4 Left Capture Switch", AIC3262_RMIC_PGA_PM_IN4,
    +			4, 1, 0),
    +	SOC_DAPM_SINGLE("CM1 Right Capture Switch", AIC3262_RMIC_PGA_MIN,
    +			6, 3, 0),
    +	SOC_DAPM_SINGLE("CM2 Right Capture Switch", AIC3262_RMIC_PGA_MIN,
    +			0, 3, 0),
    +};
    +
    +static const char * const asi1lin_text[] = {
    +	"Off", "ASI1 Left In", "ASI1 Right In", "ASI1 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi1lin_enum, AIC3262_ASI1_DAC_OUT_CNTL, 6, asi1lin_text);
    +
    +static const struct snd_kcontrol_new asi1lin_control =
    +SOC_DAPM_ENUM("ASI1LIN Route", asi1lin_enum);
    +
    +static const char * const asi1rin_text[] = {
    +	"Off", "ASI1 Right In", "ASI1 Left In", "ASI1 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi1rin_enum, AIC3262_ASI1_DAC_OUT_CNTL, 4, asi1rin_text);
    +
    +static const struct snd_kcontrol_new asi1rin_control =
    +SOC_DAPM_ENUM("ASI1RIN Route", asi1rin_enum);
    +
    +static const char * const asi2lin_text[] = {
    +	"Off", "ASI2 Left In", "ASI2 Right In", "ASI2 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi2lin_enum, AIC3262_ASI2_DAC_OUT_CNTL, 6, asi2lin_text);
    +
    +static const struct snd_kcontrol_new asi2lin_control =
    +SOC_DAPM_ENUM("ASI2LIN Route", asi2lin_enum);
    +
    +static const char * const asi2rin_text[] = {
    +	"Off", "ASI2 Right In", "ASI2 Left In", "ASI2 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi2rin_enum, AIC3262_ASI2_DAC_OUT_CNTL, 4, asi2rin_text);
    +
    +static const struct snd_kcontrol_new asi2rin_control =
    +SOC_DAPM_ENUM("ASI2RIN Route", asi2rin_enum);
    +
    +static const char * const asi3lin_text[] = {
    +	"Off", "ASI3 Left In", "ASI3 Right In", "ASI3 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi3lin_enum, AIC3262_ASI3_DAC_OUT_CNTL, 6, asi3lin_text);
    +
    +static const struct snd_kcontrol_new asi3lin_control =
    +SOC_DAPM_ENUM("ASI3LIN Route", asi3lin_enum);
    +
    +static const char * const asi3rin_text[] = {
    +	"Off", "ASI3 Right In", "ASI3 Left In", "ASI3 MonoMix In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi3rin_enum, AIC3262_ASI3_DAC_OUT_CNTL, 4, asi3rin_text);
    +
    +static const struct snd_kcontrol_new asi3rin_control =
    +SOC_DAPM_ENUM("ASI3RIN Route", asi3rin_enum);
    +
    +static const char * const dacminidspin1_text[] = {
    +	"ASI1 In", "ASI2 In", "ASI3 In", "ADC MiniDSP Out"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dacminidspin1_enum, AIC3262_MINIDSP_DATA_PORT_CNTL, 4,
    +		     dacminidspin1_text);
    +
    +static const struct snd_kcontrol_new dacminidspin1_control =
    +SOC_DAPM_ENUM("DAC MiniDSP IN1 Route Sel", dacminidspin1_enum);
    +
    +static const char * const dacminidspin2_text[] = {
    +	"ASI1 In", "ASI2 In", "ASI3 In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dacminidspin2_enum, AIC3262_MINIDSP_DATA_PORT_CNTL, 2,
    +		     dacminidspin2_text);
    +
    +static const struct snd_kcontrol_new dacminidspin2_control =
    +SOC_DAPM_ENUM("DAC MiniDSP IN2 Route Sel", dacminidspin2_enum);
    +
    +static const char * const dacminidspin3_text[] = {
    +	"ASI1 In", "ASI2 In", "ASI3 In"
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dacminidspin3_enum, AIC3262_MINIDSP_DATA_PORT_CNTL, 0,
    +		     dacminidspin3_text);
    +
    +static const struct snd_kcontrol_new dacminidspin3_control =
    +SOC_DAPM_ENUM("DAC MiniDSP IN3 Route Sel", dacminidspin3_enum);
    +
    +static const char * const adcdac_route_text[] = {
    +	"Off",
    +	"On",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(adcdac_enum, 0, 2, adcdac_route_text);
    +
    +static const struct snd_kcontrol_new adcdacroute_control =
    +SOC_DAPM_ENUM("ADC DAC Route", adcdac_enum);
    +
    +static const char * const dout1_text[] = {
    +	"ASI1 Out",
    +	"DIN1 Bypass",
    +	"DIN2 Bypass",
    +	"DIN3 Bypass",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dout1_enum, AIC3262_ASI1_DOUT_CNTL, 0, dout1_text);
    +static const struct snd_kcontrol_new dout1_control =
    +SOC_DAPM_ENUM("DOUT1 Route", dout1_enum);
    +
    +static const char * const dout2_text[] = {
    +	"ASI2 Out",
    +	"DIN1 Bypass",
    +	"DIN2 Bypass",
    +	"DIN3 Bypass",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dout2_enum, AIC3262_ASI2_DOUT_CNTL, 0, dout2_text);
    +static const struct snd_kcontrol_new dout2_control =
    +SOC_DAPM_ENUM("DOUT2 Route", dout2_enum);
    +
    +static const char * const dout3_text[] = {
    +	"ASI3 Out",
    +	"DIN1 Bypass",
    +	"DIN2 Bypass",
    +	"DIN3 Bypass",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(dout3_enum, AIC3262_ASI3_DOUT_CNTL, 0, dout3_text);
    +static const struct snd_kcontrol_new dout3_control =
    +SOC_DAPM_ENUM("DOUT3 Route", dout3_enum);
    +
    +static const char * const asi1out_text[] = {
    +	"Off",
    +	"ADC MiniDSP Out1",
    +	"ASI1In Bypass",
    +	"ASI2In Bypass",
    +	"ASI3In Bypass",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi1out_enum, AIC3262_ASI1_ADC_INPUT_CNTL,
    +		     0, asi1out_text);
    +static const struct snd_kcontrol_new asi1out_control =
    +SOC_DAPM_ENUM("ASI1OUT Route", asi1out_enum);
    +
    +static const char * const asi2out_text[] = {
    +	"Off",
    +	"ADC MiniDSP Out1",
    +	"ASI1In Bypass",
    +	"ASI2In Bypass",
    +	"ASI3In Bypass",
    +	"ADC MiniDSP Out2",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi2out_enum, AIC3262_ASI2_ADC_INPUT_CNTL,
    +		     0, asi2out_text);
    +static const struct snd_kcontrol_new asi2out_control =
    +SOC_DAPM_ENUM("ASI2OUT Route", asi2out_enum);
    +static const char * const asi3out_text[] = {
    +	"Off",
    +	"ADC MiniDSP Out1",
    +	"ASI1In Bypass",
    +	"ASI2In Bypass",
    +	"ASI3In Bypass",
    +	"Reserved",
    +	"ADC MiniDSP Out3",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi3out_enum, AIC3262_ASI3_ADC_INPUT_CNTL,
    +		     0, asi3out_text);
    +static const struct snd_kcontrol_new asi3out_control =
    +SOC_DAPM_ENUM("ASI3OUT Route", asi3out_enum);
    +static const char * const asibclk_text[] = {
    +	"DAC_CLK",
    +	"DAC_MOD_CLK",
    +	"ADC_CLK",
    +	"ADC_MOD_CLK",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(asi1bclk_enum, AIC3262_ASI1_BCLK_N_CNTL, 0, asibclk_text);
    +static const struct snd_kcontrol_new asi1bclk_control =
    +SOC_DAPM_ENUM("ASI1_BCLK Route", asi1bclk_enum);
    +
    +SOC_ENUM_SINGLE_DECL(asi2bclk_enum, AIC3262_ASI2_BCLK_N_CNTL, 0, asibclk_text);
    +static const struct snd_kcontrol_new asi2bclk_control =
    +SOC_DAPM_ENUM("ASI2_BCLK Route", asi2bclk_enum);
    +SOC_ENUM_SINGLE_DECL(asi3bclk_enum, AIC3262_ASI3_BCLK_N_CNTL, 0, asibclk_text);
    +static const struct snd_kcontrol_new asi3bclk_control =
    +SOC_DAPM_ENUM("ASI3_BCLK Route", asi3bclk_enum);
    +
    +static const char * const adc_mux_text[] = {
    +	"Analog",
    +	"Digital",
    +};
    +
    +SOC_ENUM_SINGLE_DECL(adcl_enum, AIC3262_ADC_CHANNEL_POW, 4, adc_mux_text);
    +SOC_ENUM_SINGLE_DECL(adcr_enum, AIC3262_ADC_CHANNEL_POW, 2, adc_mux_text);
    +
    +static const struct snd_kcontrol_new adcl_mux =
    +SOC_DAPM_ENUM("Left ADC Route", adcl_enum);
    +
    +static const struct snd_kcontrol_new adcr_mux =
    +SOC_DAPM_ENUM("Right ADC Route", adcr_enum);
    +
    +/**
    + * aic326x_hp_event: - To handle headphone related task before and after
    + *			headphone powrup and power down
    + * @w: pointer variable to dapm_widget
    + * @kcontrol: mixer control
    + * @event: event element information
    + *
    + * Returns 0 for success.
    + */
    +static int aic326x_hp_event(struct snd_soc_dapm_widget *w,
    +			    struct snd_kcontrol *kcontrol, int event)
    +{
    +	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
    +	struct aic3262_priv *aic3262;
    +	int reg_mask = 0;
    +	int mute_reg = 0;
    +	int ret_wbits = 0;
    +	u8 hpl_hpr;
    +
    +	aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	if (w->shift == 1) {
    +		reg_mask = AIC3262_HPL_POWER_STATUS_MASK;
    +		mute_reg = AIC3262_HPL_VOL;
    +	}
    +	if (w->shift == 0) {
    +		reg_mask = AIC3262_HPR_POWER_STATUS_MASK;
    +		mute_reg = AIC3262_HPR_VOL;
    +	}
    +	switch (event) {
    +	case SND_SOC_DAPM_PRE_PMU:
    +			snd_soc_component_update_bits(codec, AIC3262_CHARGE_PUMP_CNTL,
    +					AIC3262_DYNAMIC_OFFSET_CALIB_MASK,
    +					AIC3262_DYNAMIC_OFFSET_CALIB);
    +			snd_soc_component_write(codec, mute_reg, 0x80);
    +			snd_soc_component_update_bits(codec, AIC3262_HP_CTL,
    +					AIC3262_HP_STAGE_MASK ,
    +					AIC3262_HP_STAGE_25 << AIC3262_HP_STAGE_SHIFT);
    +		break;
    +
    +	case SND_SOC_DAPM_POST_PMU:
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_HP_FLAG, reg_mask,
    +					      reg_mask, AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "HP POST_PMU timedout\n");
    +			return -1;
    +		}
    +		snd_soc_component_update_bits(codec, AIC3262_HP_CTL,
    +			AIC3262_HP_STAGE_MASK ,
    +			AIC3262_HP_STAGE_100 << AIC3262_HP_STAGE_SHIFT);
    +		break;
    +
    +	case SND_SOC_DAPM_PRE_PMD:
    +		snd_soc_component_update_bits(codec, AIC3262_HP_CTL,
    +				AIC3262_HP_STAGE_MASK ,
    +				AIC3262_HP_STAGE_25 << AIC3262_HP_STAGE_SHIFT);
    +		hpl_hpr = snd_soc_component_read(codec, AIC3262_HP_AMP_CNTL_R1);
    +		if((hpl_hpr & 0x3) == 0x3) {
    +			snd_soc_component_update_bits(codec, AIC3262_HP_AMP_CNTL_R1,
    +						AIC3262_HPL_POWER_MASK, 0x0);
    +			mdelay(1);
    +			snd_soc_component_update_bits(codec, AIC3262_HP_AMP_CNTL_R1,
    +						AIC3262_HPR_POWER_MASK, 0x0);
    +		}
    +		break;
    +
    +	case SND_SOC_DAPM_POST_PMD:
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_HP_FLAG, reg_mask, 0,
    +					      AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "HP POST_PMD timedout\n");
    +			return -1;
    +		}
    +		snd_soc_component_write(codec, mute_reg, 0xb9);
    +		snd_soc_component_write(codec, AIC3262_POWER_CONF,
    +				snd_soc_component_read(codec, AIC3262_POWER_CONF));
    +		break;
    +	default:
    +		BUG();
    +		return -EINVAL;
    +	}
    +	return 0;
    +}
    +
    +/**
    + *aic326x_dac_event: Headset popup reduction and powering up dsps together
    + *			when they are in sync mode
    + * @w: pointer variable to dapm_widget
    + * @kcontrol: pointer to sound control
    + * @event: event element information
    + *
    + * Returns 0 for success.
    + */
    +static int aic326x_dac_event(struct snd_soc_dapm_widget *w,
    +			     struct snd_kcontrol *kcontrol, int event)
    +{
    +	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
    +	int reg_mask = 0;
    +	int ret_wbits = 0;
    +	int run_state_mask;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	int sync_needed = 0, non_sync_state = 0;
    +	int other_dsp = 0, run_state = 0;
    +
    +	if (w->shift == 7) {
    +		reg_mask = AIC3262_LDAC_POWER_STATUS_MASK;
    +		run_state_mask = AIC3XXX_COPS_MDSP_D_L;
    +	}
    +	if (w->shift == 6) {
    +		reg_mask = AIC3262_RDAC_POWER_STATUS_MASK;
    +		run_state_mask = AIC3XXX_COPS_MDSP_D_R;
    +	}
    +	switch (event) {
    +	case SND_SOC_DAPM_POST_PMU:
    +
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_DAC_FLAG, reg_mask,
    +					      reg_mask, AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +
    +		sync_needed = aic3xxx_reg_read(aic3262->control_data,
    +							AIC3262_DAC_PRB);
    +		non_sync_state = dsp_non_sync_mode(aic3262->dsp_runstate);
    +		other_dsp = aic3262->dsp_runstate & AIC3XXX_COPS_MDSP_A;
    +
    +		if (sync_needed && non_sync_state && other_dsp) {
    +			run_state = aic3262_get_runstate(
    +						aic3262->codec);
    +			aic3262_dsp_pwrdwn_status(aic3262->codec);
    +			aic3262_dsp_pwrup(aic3262->codec, run_state);
    +		}
    +		aic3262->dsp_runstate |= run_state_mask;
    +
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "DAC POST_PMU timedout\n");
    +			return -1;
    +		}
    +		break;
    +	case SND_SOC_DAPM_POST_PMD:
    +
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_DAC_FLAG, reg_mask, 0,
    +					      AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +
    +		aic3262->dsp_runstate = (aic3262->dsp_runstate &
    +					 ~run_state_mask);
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "DAC POST_PMD timedout\n");
    +			return -1;
    +		}
    +		break;
    +	default:
    +		BUG();
    +		return -EINVAL;
    +	}
    +	return 0;
    +}
    +
    +/**
    + * aic326x_spk_event: Speaker related task before and after
    + *			 headphone powrup and power down$
    + * @w: pointer variable to dapm_widget,
    + * @kcontrolr: pointer variable to sound control,
    + * @event:	integer to event,
    + *
    + * Return value: 0 for success
    + */
    +static int aic326x_spk_event(struct snd_soc_dapm_widget *w,
    +			     struct snd_kcontrol *kcontrol, int event)
    +{
    +	int reg_mask;
    +
    +	if (w->shift == 1)
    +		reg_mask = AIC3262_SPKL_POWER_STATUS_MASK;
    +	if (w->shift == 0)
    +		reg_mask = AIC3262_SPKR_POWER_STATUS_MASK;
    +	switch (event) {
    +	case SND_SOC_DAPM_POST_PMU:
    +		mdelay(1);
    +		break;
    +	case SND_SOC_DAPM_POST_PMD:
    +		mdelay(1);
    +		break;
    +	default:
    +		BUG();
    +		return -EINVAL;
    +	}
    +	return 0;
    +}
    +
    +/**$
    + * pll_power_on_event: provide delay after widget  power up
    + * @w:  pointer variable to dapm_widget,
    + * @kcontrolr: pointer variable to sound control,
    + * @event:	integer to event,
    + *
    + * Return value: 0 for success
    + */
    +static int pll_power_on_event(struct snd_soc_dapm_widget *w,
    +			      struct snd_kcontrol *kcontrol, int event)
    +{
    +	if (event == SND_SOC_DAPM_POST_PMU)
    +		mdelay(10);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_set_mode_get: To get different mode of Firmware through tinymix
    + * @kcontrolr: pointer to sound control,
    + * ucontrol: pointer to control element value,
    + *
    + * Return value: 0 for success
    + */
    +static int aic3262_set_mode_get(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
    +	struct aic3262_priv *priv_ds = snd_soc_component_get_drvdata(codec);
    +
    +	ucontrol->value.integer.value[0] = ((priv_ds->cfw_p->cur_mode << 8)
    +					    | priv_ds->cfw_p->cur_cfg);
    +
    +	return 0;
    +}
    +
    +/**
    + * aic3262_set_mode_put: To set different mode of Firmware through tinymix
    + * @kcontrolr: pointer to sound control,
    + * ucontrol: pointer to control element value,
    + *
    + * Return value: 0 for success
    + */
    +static int aic3262_set_mode_put(struct snd_kcontrol *kcontrol,
    +				struct snd_ctl_elem_value *ucontrol)
    +{
    +	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
    +	struct aic3262_priv *priv_ds = snd_soc_component_get_drvdata(codec);
    +
    +	int next_mode = 0, next_cfg = 0;
    +	int ret = 0;
    +
    +	next_mode = (ucontrol->value.integer.value[0] >> 8);
    +	next_cfg = (ucontrol->value.integer.value[0]) & 0xFF;
    +	if (priv_ds == NULL)
    +		dev_err(codec->dev, "failed to load firmware\n");
    +	else
    +		ret = aic3xxx_cfw_setmode_cfg(priv_ds->cfw_p,
    +					      next_mode, next_cfg);
    +	return ret;
    +}
    +
    +/**
    + * aic326x_adc_dsp_event: To get DSP run state to perform synchronization
    + * @w: pointer variable to dapm_widget
    + * @kcontrol: pointer to sound control
    + * @event: event element information
    + *
    + * Returns 0 for success.
    + */
    +static int aic326x_adc_dsp_event(struct snd_soc_dapm_widget *w,
    +				 struct snd_kcontrol *kcontrol, int event)
    +{
    +	struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
    +	int run_state = 0;
    +	int non_sync_state = 0, sync_needed = 0;
    +	int other_dsp = 0;
    +	int run_state_mask = 0;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	int reg_mask = 0;
    +	int ret_wbits = 0;
    +
    +	if (w->shift == 7) {
    +		reg_mask = AIC3262_LADC_POWER_MASK;
    +		run_state_mask = AIC3XXX_COPS_MDSP_A_L;
    +	}
    +	if (w->shift == 6) {
    +		reg_mask = AIC3262_RADC_POWER_MASK;
    +		run_state_mask = AIC3XXX_COPS_MDSP_A_R;
    +	}
    +	switch (event) {
    +	case SND_SOC_DAPM_POST_PMU:
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_ADC_FLAG, reg_mask,
    +					      reg_mask, AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +		sync_needed =  aic3xxx_reg_read(aic3262->control_data,
    +							AIC3262_DAC_PRB);
    +		non_sync_state = dsp_non_sync_mode(aic3262->dsp_runstate);
    +		other_dsp = aic3262->dsp_runstate & AIC3XXX_COPS_MDSP_D;
    +		if (sync_needed && non_sync_state && other_dsp) {
    +			run_state = aic3262_get_runstate(
    +						aic3262->codec);
    +			aic3262_dsp_pwrdwn_status(aic3262->codec);
    +			aic3262_dsp_pwrup(aic3262->codec, run_state);
    +		}
    +		aic3262->dsp_runstate |= run_state_mask;
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "ADC POST_PMU timedout\n");
    +			return -1;
    +		}
    +		break;
    +	case SND_SOC_DAPM_POST_PMD:
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +					      AIC3262_ADC_FLAG, reg_mask, 0,
    +					      AIC326X_TIME_DELAY,
    +					      AIC326X_DELAY_COUNTER);
    +		aic3262->dsp_runstate = (aic3262->dsp_runstate &
    +					 ~run_state_mask);
    +		if (!ret_wbits) {
    +			dev_err(codec->dev, "ADC POST_PMD timedout\n");
    +			return -1;
    +		}
    +		break;
    +	default:
    +		BUG();
    +		return -EINVAL;
    +	}
    +	return 0;
    +}
    +
    +static const struct snd_soc_dapm_widget aic3262_dapm_widgets[] = {
    +    /* TODO: Can we switch these off ? */
    +    SND_SOC_DAPM_AIF_IN("DIN1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
    +    SND_SOC_DAPM_AIF_IN("DIN2", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0),
    +    SND_SOC_DAPM_AIF_IN("DIN3", "ASI3 Playback", 0, SND_SOC_NOPM, 0, 0),
    +
    +    SND_SOC_DAPM_DAC_E("Left DAC", NULL, AIC3262_PASI_DAC_DP_SETUP, 7, 0,
    +		       aic326x_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +    SND_SOC_DAPM_DAC_E("Right DAC", NULL, AIC3262_PASI_DAC_DP_SETUP, 6, 0,
    +		       aic326x_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +
    +    /* dapm widget (path domain) for HPL Output Mixer */
    +    SND_SOC_DAPM_MIXER("HP Left Mixer", SND_SOC_NOPM, 0, 0,
    +		       &hpl_output_mixer_controls[0],
    +		       ARRAY_SIZE(hpl_output_mixer_controls)),
    +
    +    /* dapm widget (path domain) for HPR Output Mixer */
    +    SND_SOC_DAPM_MIXER("HP Right Mixer", SND_SOC_NOPM, 0, 0,
    +		       &hpr_output_mixer_controls[0],
    +		       ARRAY_SIZE(hpr_output_mixer_controls)),
    +
    +    SND_SOC_DAPM_PGA_S("HP Left Playback Driver", 3,
    +		       AIC3262_HP_AMP_CNTL_R1, 1, 0, aic326x_hp_event,
    +		       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +    SND_SOC_DAPM_PGA_S("HP Right Playback Driver", 3,
    +		       AIC3262_HP_AMP_CNTL_R1, 0, 0, aic326x_hp_event,
    +		       SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +
    +    /* dapm widget (path domain) for LOL Output Mixer */
    +    SND_SOC_DAPM_MIXER("LO Left Mixer", SND_SOC_NOPM, 0, 0,
    +		       &lol_output_mixer_controls[0],
    +		       ARRAY_SIZE(lol_output_mixer_controls)),
    +
    +    /* dapm widget (path domain) for LOR Output Mixer mixer */
    +    SND_SOC_DAPM_MIXER("LO Right Mixer", SND_SOC_NOPM, 0, 0,
    +		       &lor_output_mixer_controls[0],
    +		       ARRAY_SIZE(lor_output_mixer_controls)),
    +
    +    SND_SOC_DAPM_PGA_S("LO Left Playback Driver", 2,
    +		       AIC3262_LINE_AMP_CNTL_R1, 1, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA_S("LO Right Playback Driver", 2,
    +		       AIC3262_LINE_AMP_CNTL_R1, 0, 0, NULL, 0),
    +
    +    /* dapm widget (path domain) for SPKL Output Mixer */
    +    SND_SOC_DAPM_MIXER("SPK Left Mixer", SND_SOC_NOPM, 0, 0,
    +		       &spkl_output_mixer_controls[0],
    +		       ARRAY_SIZE(spkl_output_mixer_controls)),
    +
    +    /* dapm widget (path domain) for SPKR Output Mixer */
    +    SND_SOC_DAPM_MIXER("SPK Right Mixer", SND_SOC_NOPM, 0, 0,
    +		       &spkr_output_mixer_controls[0],
    +		       ARRAY_SIZE(spkr_output_mixer_controls)),
    +
    +    SND_SOC_DAPM_PGA_S("SPK Left Playback Driver", 3,
    +		       AIC3262_SPK_AMP_CNTL_R1, 1, 0, aic326x_spk_event,
    +		       SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
    +    SND_SOC_DAPM_PGA_S("SPK Right Playback Driver", 3,
    +		       AIC3262_SPK_AMP_CNTL_R1, 0, 0, aic326x_spk_event,
    +		       SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
    +
    +    /* dapm widget (path domain) for SPKR Output Mixer */
    +    SND_SOC_DAPM_MIXER("REC Mixer", SND_SOC_NOPM, 0, 0,
    +		       &rec_output_mixer_controls[0],
    +		       ARRAY_SIZE(rec_output_mixer_controls)),
    +
    +    SND_SOC_DAPM_PGA_S("RECP Playback Driver", 3, AIC3262_REC_AMP_CNTL_R5,
    +		       7, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA_S("RECM Playback Driver", 3, AIC3262_REC_AMP_CNTL_R5,
    +		       6, 0, NULL, 0),
    +
    +    SND_SOC_DAPM_MUX("ASI1LIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi1lin_control),
    +    SND_SOC_DAPM_MUX("ASI1RIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi1rin_control),
    +    SND_SOC_DAPM_MUX("ASI2LIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi2lin_control),
    +    SND_SOC_DAPM_MUX("ASI2RIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi2rin_control),
    +    SND_SOC_DAPM_MUX("ASI3LIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi3lin_control),
    +    SND_SOC_DAPM_MUX("ASI3RIN Route",
    +		     SND_SOC_NOPM, 0, 0, &asi3rin_control),
    +
    +    SND_SOC_DAPM_PGA("ASI1LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI1RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3LIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3RIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI1MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3MonoMixIN", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    /* TODO: Can we switch the ASIxIN off? */
    +    SND_SOC_DAPM_PGA("ASI1IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3IN Port", SND_SOC_NOPM, 0, 0, NULL, 0),
    +
    +    SND_SOC_DAPM_MUX("DAC MiniDSP IN1 Route",
    +		     SND_SOC_NOPM, 0, 0, &dacminidspin1_control),
    +    SND_SOC_DAPM_MUX("DAC MiniDSP IN2 Route",
    +		     SND_SOC_NOPM, 0, 0, &dacminidspin2_control),
    +    SND_SOC_DAPM_MUX("DAC MiniDSP IN3 Route",
    +		     SND_SOC_NOPM, 0, 0, &dacminidspin3_control),
    +
    +    SND_SOC_DAPM_MUX("ADC DAC Route",
    +		     SND_SOC_NOPM, 0, 0, &adcdacroute_control),
    +
    +    SND_SOC_DAPM_PGA("CM", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("CM1 Left Capture", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("CM2 Left Capture", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("CM1 Right Capture", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("CM2 Right Capture", SND_SOC_NOPM, 0, 0, NULL, 0),
    +
    +    /* TODO: Can we switch these off ? */
    +    SND_SOC_DAPM_AIF_OUT("DOUT1", "ASI1 Capture", 0, SND_SOC_NOPM, 0, 0),
    +    SND_SOC_DAPM_AIF_OUT("DOUT2", "ASI2 Capture", 0, SND_SOC_NOPM, 0, 0),
    +    SND_SOC_DAPM_AIF_OUT("DOUT3", "ASI3 Capture", 0, SND_SOC_NOPM, 0, 0),
    +
    +    SND_SOC_DAPM_MUX("DOUT1 Route",
    +		     SND_SOC_NOPM, 0, 0, &dout1_control),
    +    SND_SOC_DAPM_MUX("DOUT2 Route",
    +		     SND_SOC_NOPM, 0, 0, &dout2_control),
    +    SND_SOC_DAPM_MUX("DOUT3 Route",
    +		     SND_SOC_NOPM, 0, 0, &dout3_control),
    +
    +    SND_SOC_DAPM_PGA("ASI1OUT", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI2OUT", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ASI3OUT", SND_SOC_NOPM, 0, 0, NULL, 0),
    +
    +    SND_SOC_DAPM_MUX("ASI1OUT Route",
    +		     SND_SOC_NOPM, 0, 0, &asi1out_control),
    +    SND_SOC_DAPM_MUX("ASI2OUT Route",
    +		     SND_SOC_NOPM, 0, 0, &asi2out_control),
    +    SND_SOC_DAPM_MUX("ASI3OUT Route",
    +		     SND_SOC_NOPM, 0, 0, &asi3out_control),
    +
    +    /* TODO: Can we switch the ASI1 OUT1 off? */
    +    /* TODO: Can we switch them off? */
    +    SND_SOC_DAPM_PGA("ADC MiniDSP OUT1", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ADC MiniDSP OUT2", SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA("ADC MiniDSP OUT3", SND_SOC_NOPM, 0, 0, NULL, 0),
    +
    +    SND_SOC_DAPM_MUX("Left ADC Route", SND_SOC_NOPM, 0, 0, &adcl_mux),
    +    SND_SOC_DAPM_MUX("Right ADC Route", SND_SOC_NOPM, 0, 0, &adcr_mux),
    +
    +    SND_SOC_DAPM_ADC_E("Left ADC", NULL, AIC3262_ADC_CHANNEL_POW, 7, 0,
    +		       aic326x_adc_dsp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +    SND_SOC_DAPM_ADC_E("Right ADC", NULL, AIC3262_ADC_CHANNEL_POW, 6, 0,
    +		       aic326x_adc_dsp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
    +
    +    SND_SOC_DAPM_PGA_S("Left MicPGA", 0, AIC3262_MICL_PGA, 7, 1, NULL, 0),
    +    SND_SOC_DAPM_PGA_S("Right MicPGA", 0, AIC3262_MICR_PGA, 7, 1, NULL, 0),
    +
    +    SND_SOC_DAPM_PGA_S("MA Left Playback PGA", 1, AIC3262_MA_CNTL,
    +		       3, 0, NULL, 0),
    +    SND_SOC_DAPM_PGA_S("MA Right Playback PGA", 1, AIC3262_MA_CNTL,
    +		       2, 0, NULL, 0),
    +
    +    /* dapm widget for MAL PGA Mixer */
    +    SND_SOC_DAPM_MIXER("MA Left PGA Mixer", SND_SOC_NOPM, 0, 0,
    +		       &mal_pga_mixer_controls[0],
    +		       ARRAY_SIZE(mal_pga_mixer_controls)),
    +
    +    /* dapm widget for MAR PGA Mixer */
    +    SND_SOC_DAPM_MIXER("MA Right PGA Mixer", SND_SOC_NOPM, 0, 0,
    +		       &mar_pga_mixer_controls[0],
    +		       ARRAY_SIZE(mar_pga_mixer_controls)),
    +
    +    /* dapm widget for Left Input Mixer */
    +    SND_SOC_DAPM_MIXER("Left Input Mixer", SND_SOC_NOPM, 0, 0,
    +		       &left_input_mixer_controls[0],
    +		       ARRAY_SIZE(left_input_mixer_controls)),
    +
    +    /* dapm widget for Right Input Mixer */
    +    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_OUTPUT("HP Left Playback"),
    +    SND_SOC_DAPM_OUTPUT("HP Right Playback"),
    +    SND_SOC_DAPM_OUTPUT("LO Left Playback"),
    +    SND_SOC_DAPM_OUTPUT("LO Right Playback"),
    +    SND_SOC_DAPM_OUTPUT("SPK Left Playback"),
    +    SND_SOC_DAPM_OUTPUT("SPK Right Playback"),
    +    SND_SOC_DAPM_OUTPUT("RECP Playback"),
    +    SND_SOC_DAPM_OUTPUT("RECM Playback"),
    +
    +    SND_SOC_DAPM_INPUT("IN1 Left Capture"),
    +    SND_SOC_DAPM_INPUT("IN2 Left Capture"),
    +    SND_SOC_DAPM_INPUT("IN3 Left Capture"),
    +    SND_SOC_DAPM_INPUT("IN4 Left Capture"),
    +    SND_SOC_DAPM_INPUT("IN1 Right Capture"),
    +    SND_SOC_DAPM_INPUT("IN2 Right Capture"),
    +    SND_SOC_DAPM_INPUT("IN3 Right Capture"),
    +    SND_SOC_DAPM_INPUT("IN4 Right Capture"),
    +    SND_SOC_DAPM_INPUT("Left DMIC Capture"),
    +    SND_SOC_DAPM_INPUT("Right DMIC Capture"),
    +
    +    SND_SOC_DAPM_MICBIAS("Mic Bias Ext", AIC3262_MIC_BIAS_CNTL, 6, 0),
    +    SND_SOC_DAPM_MICBIAS("Mic Bias Int", AIC3262_MIC_BIAS_CNTL, 2, 0),
    +
    +    SND_SOC_DAPM_SUPPLY_S("PLLCLK", 0, AIC3262_PLL_PR_POW_REG, 7, 0,
    +			  pll_power_on_event, SND_SOC_DAPM_POST_PMU),
    +    SND_SOC_DAPM_SUPPLY_S("DACCLK", 2, AIC3262_NDAC_DIV_POW_REG, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("CODEC_CLK_IN", 1, SND_SOC_NOPM, 0, 0, NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("DAC_MOD_CLK", 3, AIC3262_MDAC_DIV_POW_REG,
    +			  7, 0, NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ADCCLK", 2, AIC3262_NADC_DIV_POW_REG, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ADC_MOD_CLK", 3, AIC3262_MADC_DIV_POW_REG,
    +			  7, 0, NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI1_BCLK", 4, AIC3262_ASI1_BCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI1_WCLK", 4, AIC3262_ASI1_WCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI2_BCLK", 4, AIC3262_ASI2_BCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI2_WCLK", 4, AIC3262_ASI2_WCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI3_BCLK", 4, AIC3262_ASI3_BCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_SUPPLY_S("ASI3_WCLK", 4, AIC3262_ASI3_WCLK_N, 7, 0,
    +			  NULL, 0),
    +    SND_SOC_DAPM_MUX("ASI1_BCLK Route",
    +		     SND_SOC_NOPM, 0, 0, &asi1bclk_control),
    +    SND_SOC_DAPM_MUX("ASI2_BCLK Route",
    +		     SND_SOC_NOPM, 0, 0, &asi2bclk_control),
    +    SND_SOC_DAPM_MUX("ASI3_BCLK Route",
    +		     SND_SOC_NOPM, 0, 0, &asi3bclk_control),
    +};
    +
    +static const struct snd_soc_dapm_route aic3262_dapm_routes[] = {
    +	/* TODO: Do we need only DACCLK for ASIIN's and ADCCLK for ASIOUT??? */
    +	/* Clock portion */
    +	{"CODEC_CLK_IN", NULL, "PLLCLK"},
    +	{"DACCLK", NULL, "CODEC_CLK_IN"},
    +	{"ADCCLK", NULL, "CODEC_CLK_IN"},
    +	{"DAC_MOD_CLK", NULL, "DACCLK"},
    +#ifdef AIC3262_SYNC_MODE
    +	{"ADC_MOD_CLK", NULL, "DACCLK"},
    +#else
    +	{"ADC_MOD_CLK", NULL, "ADCCLK"},
    +#endif
    +	{"ASI1_BCLK Route", NULL /*"DAC_CLK"*/, "DACCLK"},
    +	{"ASI1_BCLK Route", NULL /*/"DAC_MOD_CLK"*/, "DAC_MOD_CLK"},
    +	{"ASI1_BCLK Route", NULL /*"ADC_CLK"*/, "ADCCLK"},
    +	{"ASI1_BCLK Route", NULL /*"ADC_MOD_CLK"*/, "ADC_MOD_CLK"},
    +
    +	{"ASI2_BCLK Route", NULL /*"DAC_CLK"*/, "DACCLK"},
    +	{"ASI2_BCLK Route", NULL /*/"DAC_MOD_CLK"*/, "DAC_MOD_CLK"},
    +	{"ASI2_BCLK Route", NULL /*"ADC_CLK"*/, "ADCCLK"},
    +	{"ASI2_BCLK Route", NULL /*"ADC_MOD_CLK"*/, "ADC_MOD_CLK"},
    +
    +	{"ASI3_BCLK Route", NULL /*"DAC_CLK"*/, "DACCLK"},
    +	{"ASI3_BCLK Route", NULL /*/"DAC_MOD_CLK"*/, "DAC_MOD_CLK"},
    +	{"ASI3_BCLK Route", NULL /*"ADC_CLK"*/, "ADCCLK"},
    +	{"ASI3_BCLK Route", NULL /*"ADC_MOD_CLK"*/, "ADC_MOD_CLK"},
    +
    +#ifdef AIC3262_ASI1_MASTER
    +	{"DIN1", NULL, "ASI1_BCLK Route"},
    +	{"DOUT1", NULL, "ASI1_BCLK Route"},
    +	{"DIN1", NULL, "ASI1_WCLK"},
    +	{"DOUT1", NULL, "ASI1_WCLK"},
    +	{"DIN1", NULL, "ASI1_BCLK"},
    +	{"DOUT1", NULL, "ASI1_BCLK"},
    +#endif
    +
    +#ifdef AIC3262_ASI2_MASTER
    +	{"DIN2", NULL, "ASI2_BCLK Route"},
    +	{"DOUT2", NULL, "ASI2_BCLK Route"},
    +	{"DIN2", NULL, "ASI2_WCLK"},
    +	{"DOUT2", NULL, "ASI2_WCLK"},
    +	{"DIN2", NULL, "ASI2_BCLK"},
    +	{"DOUT2", NULL, "ASI2_BCLK"},
    +#endif
    +#ifdef AIC3262_ASI3_MASTER
    +	{"DIN3", NULL, "ASI3_BCLK"},
    +	{"DOUT3", NULL, "ASI3_BCLK"},
    +	{"DIN3", NULL, "ASI3_BCLK Route"},
    +	{"DOUT3", NULL, "ASI3_BCLK Route"},
    +	{"DIN3", NULL, "ASI3_WCLK"},
    +	{"DOUT3", NULL, "ASI3_WCLK"},
    +#endif
    +	{"Left DAC", NULL, "DAC_MOD_CLK"},
    +	{"Right DAC", NULL, "DAC_MOD_CLK"},
    +	/* When we are master, ASI bclk and wclk are generated by
    +	* DAC_MOD_CLK, so we put them as dependency for ADC too.
    +	*/
    +	{"Left ADC", NULL, "DAC_MOD_CLK"},
    +	{"Right ADC", NULL, "DAC_MOD_CLK"},
    +	{"Left ADC", NULL, "ADC_MOD_CLK"},
    +	{"Right ADC", NULL, "ADC_MOD_CLK"},
    +	/* Playback (DAC) Portion */
    +	{"HP Left Mixer", "Left DAC Playback Switch", "Left DAC"},
    +	{"HP Left Mixer", "MA Left Playback Switch", "MA Left Playback PGA"},
    +	{"HP Left Mixer", "LO Left-B1 Playback Volume", "LO Left Playback"},
    +
    +	{"HP Right Mixer", "LO Right-B1 Playback Volume", "LO Right Playback"},
    +	{"HP Right Mixer", "Left DAC Playback Switch", "Left DAC"},
    +	{"HP Right Mixer", "Right DAC Playback Switch", "Right DAC"},
    +	{"HP Right Mixer", "MA Right Playback Switch", "MA Right Playback PGA"},
    +
    +	{"HP Left Playback Driver", NULL, "HP Left Mixer"},
    +	{"HP Right Playback Driver", NULL, "HP Right Mixer"},
    +
    +	{"HP Left Playback", NULL, "HP Left Playback Driver"},
    +	{"HP Right Playback", NULL, "HP Right Playback Driver"},
    +
    +	{"LO Left Mixer", "MA Left Playback Switch", "MA Left Playback PGA"},
    +	{"LO Left Mixer", "IN1 Left-B Capture Switch", "IN1 Left Capture"},
    +	{"LO Left Mixer", "Left DAC Playback Switch", "Left DAC"},
    +	{"LO Left Mixer", "Right DAC Playback Switch", "Right DAC"},
    +
    +	{"LO Right Mixer", "LO Left Playback Switch", "LO Left Playback"},
    +	{"LO Right Mixer", "Right DAC Playback Switch", "Right DAC"},
    +	{"LO Right Mixer", "MA Right Playback Switch", "MA Right Playback PGA"},
    +	{"LO Right Mixer", "IN1 Right-B Capture Switch", "IN1 Right Capture"},
    +
    +	{"LO Left Playback Driver", NULL, "LO Left Mixer"},
    +	{"LO Right Playback Driver", NULL, "LO Right Mixer"},
    +
    +	{"LO Left Playback", NULL, "LO Left Playback Driver"},
    +	{"LO Right Playback", NULL, "LO Right Playback Driver"},
    +
    +	{"REC Mixer", "LO Left-B2 Playback Volume", "LO Left Playback"},
    +	{"REC Mixer", "IN1 Left Capture Volume", "IN1 Left Capture"},
    +	{"REC Mixer", "IN1 Right Capture Volume", "IN1 Right Capture"},
    +	{"REC Mixer", "LO Right-B2 Playback Volume", "LO Right Playback"},
    +
    +	{"RECP Playback Driver", NULL, "REC Mixer"},
    +	{"RECM Playback Driver", NULL, "REC Mixer"},
    +
    +	{"RECP Playback", NULL, "RECP Playback Driver"},
    +	{"RECM Playback", NULL, "RECM Playback Driver"},
    +
    +	{"SPK Left Mixer", "MA Left Playback Switch", "MA Left Playback PGA"},
    +	{"SPK Left Mixer", "LO Left Playback Volume", "LO Left Playback"},
    +	{"SPK Left Mixer", "SPR_IN Switch", "SPK Right Mixer"},
    +
    +	{"SPK Right Mixer", "LO Right Playback Volume", "LO Right Playback"},
    +	{"SPK Right Mixer", "MA Right Playback Switch", "MA Right Playback PGA"},
    +
    +	{"SPK Left Playback Driver", NULL, "SPK Left Mixer"},
    +	{"SPK Right Playback Driver", NULL, "SPK Right Mixer"},
    +
    +	{"SPK Left Playback", NULL, "SPK Left Playback Driver"},
    +	{"SPK Right Playback", NULL, "SPK Right Playback Driver"},
    +	/* ASI Input routing */
    +	{"ASI1LIN", NULL, "DIN1"},
    +	{"ASI1RIN", NULL, "DIN1"},
    +	{"ASI1MonoMixIN", NULL, "DIN1"},
    +	{"ASI2LIN", NULL, "DIN2"},
    +	{"ASI2RIN", NULL, "DIN2"},
    +	{"ASI2MonoMixIN", NULL, "DIN2"},
    +	{"ASI3LIN", NULL, "DIN3"},
    +	{"ASI3RIN", NULL, "DIN3"},
    +	{"ASI3MonoMixIN", NULL, "DIN3"},
    +
    +	{"ASI1LIN Route", "ASI1 Left In", "ASI1LIN"},
    +	{"ASI1LIN Route", "ASI1 Right In", "ASI1RIN"},
    +	{"ASI1LIN Route", "ASI1 MonoMix In", "ASI1MonoMixIN"},
    +
    +	{"ASI1RIN Route", "ASI1 Right In", "ASI1RIN"},
    +	{"ASI1RIN Route", "ASI1 Left In", "ASI1LIN"},
    +	{"ASI1RIN Route", "ASI1 MonoMix In", "ASI1MonoMixIN"},
    +
    +	{"ASI2LIN Route", "ASI2 Left In", "ASI2LIN"},
    +	{"ASI2LIN Route", "ASI2 Right In", "ASI2RIN"},
    +	{"ASI2LIN Route", "ASI2 MonoMix In", "ASI2MonoMixIN"},
    +
    +	{"ASI2RIN Route", "ASI2 Right In", "ASI2RIN"},
    +	{"ASI2RIN Route", "ASI2 Left In", "ASI2LIN"},
    +	{"ASI2RIN Route", "ASI2 MonoMix In", "ASI2MonoMixIN"},
    +
    +	{"ASI3LIN Route", "ASI3 Left In", "ASI3LIN"},
    +	{"ASI3LIN Route", "ASI3 Right In", "ASI3RIN"},
    +	{"ASI3LIN Route", "ASI3 MonoMix In", "ASI3MonoMixIN"},
    +
    +	{"ASI3RIN Route", "ASI3 Right In", "ASI3RIN"},
    +	{"ASI3RIN Route", "ASI3 Left In", "ASI3LIN"},
    +	{"ASI3RIN Route", "ASI3 MonoMix In", "ASI3MonoMixIN"},
    +
    +	{"ASI1IN Port", NULL, "ASI1LIN Route"},
    +	{"ASI1IN Port", NULL, "ASI1RIN Route"},
    +	{"ASI2IN Port", NULL, "ASI2LIN Route"},
    +	{"ASI2IN Port", NULL, "ASI2RIN Route"},
    +	{"ASI3IN Port", NULL, "ASI3LIN Route"},
    +	{"ASI3IN Port", NULL, "ASI3RIN Route"},
    +
    +	{"DAC MiniDSP IN1 Route", "ASI1 In", "ASI1IN Port"},
    +	{"DAC MiniDSP IN1 Route", "ASI2 In", "ASI2IN Port"},
    +	{"DAC MiniDSP IN1 Route", "ASI3 In", "ASI3IN Port"},
    +	{"DAC MiniDSP IN1 Route", "ADC MiniDSP Out", "ADC MiniDSP OUT1"},
    +
    +	{"DAC MiniDSP IN2 Route", "ASI1 In", "ASI1IN Port"},
    +	{"DAC MiniDSP IN2 Route", "ASI2 In", "ASI2IN Port"},
    +	{"DAC MiniDSP IN2 Route", "ASI3 In", "ASI3IN Port"},
    +
    +	{"DAC MiniDSP IN3 Route", "ASI1 In", "ASI1IN Port"},
    +	{"DAC MiniDSP IN3 Route", "ASI2 In", "ASI2IN Port"},
    +	{"DAC MiniDSP IN3 Route", "ASI3 In", "ASI3IN Port"},
    +
    +	{"Left DAC", NULL, "DAC MiniDSP IN1 Route"},
    +	{"Right DAC", NULL, "DAC MiniDSP IN1 Route"},
    +	{"Left DAC", NULL, "DAC MiniDSP IN2 Route"},
    +	{"Right DAC", NULL, "DAC MiniDSP IN2 Route"},
    +	{"Left DAC", NULL, "DAC MiniDSP IN3 Route"},
    +	{"Right DAC", NULL, "DAC MiniDSP IN3 Route"},
    +
    +	/* Mixer Amplifier */
    +	{"MA Left PGA Mixer", "IN1 Left Capture Switch", "IN1 Left Capture"},
    +	{"MA Left PGA Mixer", "Left MicPGA Volume", "Left MicPGA"},
    +
    +	{"MA Left Playback PGA", NULL, "MA Left PGA Mixer"},
    +
    +	{"MA Right PGA Mixer", "IN1 Right Capture Switch", "IN1 Right Capture"},
    +	{"MA Right PGA Mixer", "Right MicPGA Volume", "Right MicPGA"},
    +
    +	{"MA Right Playback PGA", NULL, "MA Right PGA Mixer"},
    +
    +	/* Virtual connection between DAC and ADC for miniDSP IPC */
    +	{"ADC DAC Route", "On", "Left ADC"},
    +	{"ADC DAC Route", "On", "Right ADC"},
    +
    +	{"Left DAC", NULL, "ADC DAC Route"},
    +	{"Right DAC", NULL, "ADC DAC Route"},
    +
    +	/* Capture (ADC) portions */
    +	/* Left Positive PGA input */
    +	{"Left Input Mixer", "IN1 Left Capture Switch", "IN1 Left Capture"},
    +	{"Left Input Mixer", "IN2 Left Capture Switch", "IN2 Left Capture"},
    +	{"Left Input Mixer", "IN3 Left Capture Switch", "IN3 Left Capture"},
    +	{"Left Input Mixer", "IN4 Left Capture Switch", "IN4 Left Capture"},
    +	{"Left Input Mixer", "IN1 Right Capture Switch", "IN1 Right Capture"},
    +	/* Left Negative PGA input */
    +	{"Left Input Mixer", "IN2 Right Capture Switch", "IN2 Right Capture"},
    +	{"Left Input Mixer", "IN3 Right Capture Switch", "IN3 Right Capture"},
    +	{"Left Input Mixer", "IN4 Right Capture Switch", "IN4 Right Capture"},
    +	{"Left Input Mixer", "CM2 Left Capture Switch", "CM2 Left Capture"},
    +	{"Left Input Mixer", "CM1 Left Capture Switch", "CM1 Left Capture"},
    +
    +	/* Right Positive PGA Input */
    +	{"Right Input Mixer", "IN1 Right Capture Switch", "IN1 Right Capture"},
    +	{"Right Input Mixer", "IN2 Right Capture Switch", "IN2 Right Capture"},
    +	{"Right Input Mixer", "IN3 Right Capture Switch", "IN3 Right Capture"},
    +	{"Right Input Mixer", "IN4 Right Capture Switch", "IN4 Right Capture"},
    +	{"Right Input Mixer", "IN2 Left Capture Switch", "IN2 Left Capture"},
    +	/* Right Negative PGA Input */
    +	{"Right Input Mixer", "IN1 Left Capture Switch", "IN1 Left Capture"},
    +	{"Right Input Mixer", "IN3 Left Capture Switch", "IN3 Left Capture"},
    +	{"Right Input Mixer", "IN4 Left Capture Switch", "IN4 Left Capture"},
    +	{"Right Input Mixer", "CM1 Right Capture Switch", "CM1 Right Capture"},
    +	{"Right Input Mixer", "CM2 Right Capture Switch", "CM2 Right Capture"},
    +
    +	{"CM1 Left Capture", NULL, "CM"},
    +	{"CM2 Left Capture", NULL, "CM"},
    +	{"CM1 Right Capture", NULL, "CM"},
    +	{"CM2 Right Capture", NULL, "CM"},
    +
    +	{"Left MicPGA", NULL, "Left Input Mixer"},
    +	{"Right MicPGA", NULL, "Right Input Mixer"},
    +
    +	{"Left ADC Route", "Analog", "Left MicPGA"},
    +	{"Left ADC Route", "Digital", "Left DMIC Capture"},
    +
    +	{"Right ADC Route", "Analog", "Right MicPGA"},
    +	{"Right ADC Route", "Digital", "Right DMIC Capture"},
    +
    +	{"Left ADC", NULL, "Left ADC Route"},
    +	{"Right ADC", NULL, "Right ADC Route"},
    +
    +	/* ASI Output Routing */
    +	{"ADC MiniDSP OUT1", NULL, "Left ADC"},
    +	{"ADC MiniDSP OUT1", NULL, "Right ADC"},
    +	{"ADC MiniDSP OUT2", NULL, "Left ADC"},
    +	{"ADC MiniDSP OUT2", NULL, "Right ADC"},
    +	{"ADC MiniDSP OUT3", NULL, "Left ADC"},
    +	{"ADC MiniDSP OUT3", NULL, "Right ADC"},
    +
    +	{"ASI1OUT Route", "ADC MiniDSP Out1", "ADC MiniDSP OUT1"},
    +	{"ASI1OUT Route", "ASI1In Bypass", "ASI1IN Port"},
    +	{"ASI1OUT Route", "ASI2In Bypass", "ASI2IN Port"},
    +	{"ASI1OUT Route", "ASI3In Bypass", "ASI3IN Port"},
    +
    +	{"ASI2OUT Route", "ADC MiniDSP Out1", "ADC MiniDSP OUT1"},
    +	{"ASI2OUT Route", "ASI1In Bypass", "ASI1IN Port"},
    +	{"ASI2OUT Route", "ASI2In Bypass", "ASI2IN Port"},
    +	{"ASI2OUT Route", "ASI3In Bypass", "ASI3IN Port"},
    +	{"ASI2OUT Route", "ADC MiniDSP Out2", "ADC MiniDSP OUT2"},
    +
    +	{"ASI3OUT Route", "ADC MiniDSP Out1", "ADC MiniDSP OUT1"},
    +	{"ASI3OUT Route", "ASI1In Bypass", "ASI1IN Port"},
    +	{"ASI3OUT Route", "ASI2In Bypass", "ASI2IN Port"},
    +	{"ASI3OUT Route", "ASI3In Bypass", "ASI3IN Port"},
    +	{"ASI3OUT Route", "ADC MiniDSP Out3", "ADC MiniDSP OUT3"},
    +
    +	{"ASI1OUT", NULL, "ASI1OUT Route"},
    +	{"ASI2OUT", NULL, "ASI2OUT Route"},
    +	{"ASI3OUT", NULL, "ASI3OUT Route"},
    +
    +	{"DOUT1 Route", "ASI1 Out", "ASI1OUT"},
    +	{"DOUT1 Route", "DIN1 Bypass", "DIN1"},
    +	{"DOUT1 Route", "DIN2 Bypass", "DIN2"},
    +	{"DOUT1 Route", "DIN3 Bypass", "DIN3"},
    +
    +	{"DOUT2 Route", "ASI2 Out", "ASI2OUT"},
    +	{"DOUT2 Route", "DIN1 Bypass", "DIN1"},
    +	{"DOUT2 Route", "DIN2 Bypass", "DIN2"},
    +	{"DOUT2 Route", "DIN3 Bypass", "DIN3"},
    +
    +	{"DOUT3 Route", "ASI3 Out", "ASI3OUT"},
    +	{"DOUT3 Route", "DIN1 Bypass", "DIN1"},
    +	{"DOUT3 Route", "DIN2 Bypass", "DIN2"},
    +	{"DOUT3 Route", "DIN3 Bypass", "DIN3"},
    +
    +	{"DOUT1", NULL, "DOUT1 Route"},
    +	{"DOUT2", NULL, "DOUT2 Route"},
    +	{"DOUT3", NULL, "DOUT3 Route"},
    +};
    +
    +#define AIC3262_DAPM_ROUTE_NUM (ARRAY_SIZE(aic3262_dapm_routes)/ \
    +					sizeof(struct snd_soc_dapm_route))
    +/* aic3262_firmware_load:   This function is called by the
    + *		request_firmware_nowait function as soon
    + *		as the firmware has been loaded from the file.
    + *		The firmware structure contains the data and$
    + *		the size of the firmware loaded.
    + * @fw: pointer to firmware file to be dowloaded
    + * @context: pointer variable to codec
    + *
    + * Returns 0 for success.
    + */
    +static void aic3262_firmware_load(const struct firmware *fw, void *context)
    +{
    +	struct snd_soc_component *codec = context;
    +	struct aic3262_priv *private_ds = snd_soc_component_get_drvdata(codec);
    +	int ret = 0;
    +
    +	aic3xxx_cfw_lock(private_ds->cfw_p, 1);
    +	if (private_ds->cur_fw != NULL)
    +		release_firmware(private_ds->cur_fw);
    +	private_ds->cur_fw = NULL;
    +
    +	if (fw != NULL) {
    +		dev_dbg(codec->dev, "Firmware binary load\n");
    +		private_ds->cur_fw = (void *)fw;
    +		ret = aic3xxx_cfw_reload(private_ds->cfw_p, (void *)fw->data,
    +			fw->size);
    +		if (ret < 0) { /* reload failed */
    +			dev_err(codec->dev, "Firmware binary load failed\n");
    +			release_firmware(private_ds->cur_fw);
    +			private_ds->cur_fw = NULL;
    +			fw = NULL;
    +		}
    +	} else {
    +		/* request_firmware failed*/
    +		/* could not locate file tlv320aic3262_fw_v1.bin
    +			under /vendor/firmare
    +		*/
    +		dev_err(codec->dev, "request_firmware failed\n");
    +		ret = -1;
    +	}
    +
    +	aic3xxx_cfw_lock(private_ds->cfw_p, 0);
    +	if (ret >= 0) {
    +		/*init function for transition */
    +		aic3xxx_cfw_transition(private_ds->cfw_p, "INIT");
    +		/* add firmware modes */
    +		aic3xxx_cfw_add_modes(codec, private_ds->cfw_p);
    +		/* add runtime controls */
    +		aic3xxx_cfw_add_controls(codec, private_ds->cfw_p);
    +		/* set the default firmware mode */
    +		aic3xxx_cfw_setmode_cfg(private_ds->cfw_p, 0, 0);
    +	}
    +
    +}
    +
    +/*=========================================================
    +
    + headset work and headphone/headset jack interrupt handlers
    +
    + ========================================================*/
    +
    +enum headset_accessory_state {
    +	BIT_NO_ACCESSORY = 0,
    +	BIT_HEADSET = (1 << 0),
    +	BIT_HEADPHONE = (1 << 1),
    +};
    +
    +/**
    + * aic3262_hs_jack_report: Report jack notication to upper layor
    + * @codec: pointer variable to codec having information related to codec
    + * @jack: Pointer variable to snd_soc_jack having information of codec
    + *		 and pin number$
    + * @report: Provides informaton of whether it is headphone or microphone
    + *
    +*/
    +static void aic3262_hs_jack_report(struct snd_soc_component *codec,
    +				   struct snd_soc_jack *jack, int report)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	int status, state = 0, switch_state = BIT_NO_ACCESSORY;
    +
    +	mutex_lock(&aic3262->mutex);
    +
    +	/* Sync status */
    +	status = snd_soc_component_read(codec, AIC3262_DAC_FLAG);
    +	/* We will check only stereo MIC and headphone */
    +	switch (status & AIC3262_JACK_TYPE_MASK) {
    +	case AIC3262_JACK_WITH_MIC:
    +		state |= SND_JACK_HEADSET;
    +		break;
    +	case AIC3262_JACK_WITHOUT_MIC:
    +		state |= SND_JACK_HEADPHONE;
    +	}
    +
    +	mutex_unlock(&aic3262->mutex);
    +
    +	snd_soc_jack_report(jack, state, report);
    +
    +	if ((state & SND_JACK_HEADSET) == SND_JACK_HEADSET)
    +		switch_state |= BIT_HEADSET;
    +	else if (state & SND_JACK_HEADPHONE)
    +		switch_state |= BIT_HEADPHONE;
    +
    +}
    +
    +/**
    + * aic3262_hs_jack_detect: Detect headphone jack during boot time
    + * @codec: pointer variable to codec having information related to codec
    + * @jack: Pointer variable to snd_soc_jack having information of codec
    + *	     and pin number$
    + * @report: Provides informaton of whether it is headphone or microphone
    + *
    +*/
    +void aic3262_hs_jack_detect(struct snd_soc_component *codec,
    +			    struct snd_soc_jack *jack, int report)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	struct aic3262_jack_data *hs_jack = &aic3262->hs_jack;
    +
    +	hs_jack->jack = jack;
    +	hs_jack->report = report;
    +	aic3262_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
    +}
    +EXPORT_SYMBOL_GPL(aic3262_hs_jack_detect);
    +/**
    + * aic3262_accessory_work: Finished bottom half work from headphone jack
    + *		insertion interupt
    + * @work: pionter variable to work_struct which is maintaining work queqe
    + *
    +*/
    +static void aic3262_accessory_work(struct work_struct *work)
    +{
    +	struct aic3262_priv *aic3262 = container_of(work,
    +						    struct aic3262_priv,
    +						    delayed_work.work);
    +	struct snd_soc_component *codec = aic3262->codec;
    +	struct aic3262_jack_data *hs_jack = &aic3262->hs_jack;
    +	aic3262_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
    +}
    +
    +/**
    + * aic3262_audio_handler: audio interrupt handler called
    + *		when interupt is generated
    + * @irq: provides interupt number which is assigned by aic3262_request_irq,
    + * @data having information of data passed by aic3262_request_irq last arg,
    + *
    + * Return IRQ_HANDLED(means interupt handeled successfully)
    +*/
    +static irqreturn_t aic3262_audio_handler(int irq, void *data)
    +{
    +	struct snd_soc_component *codec = data;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	queue_delayed_work(aic3262->workqueue, &aic3262->delayed_work,
    +			   msecs_to_jiffies(200));
    +	return IRQ_HANDLED;
    +}
    +
    +/**
    + * Methods for CFW Operations
    + *
    + * Due to incompatibilites between structures used by MFD and CFW
    + * we need to transform the register format before linking to
    + * CFW operations.
    + */
    +static inline unsigned int aic3262_ops_cfw2reg(unsigned int reg)
    +{
    +	union cfw_register *c = (union cfw_register *) ®
    +	union aic3xxx_reg_union mreg;
    +
    +	mreg.aic3xxx_register.offset = c->offset;
    +	mreg.aic3xxx_register.page = c->page;
    +	mreg.aic3xxx_register.book = c->book;
    +	mreg.aic3xxx_register.reserved = 0;
    +	return mreg.aic3xxx_register_int;
    +}
    +static int aic3262_ops_reg_read(struct snd_soc_component *codec, unsigned int reg)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_reg_read(aic3262->control_data, aic3262_ops_cfw2reg(reg));
    +}
    +
    +static int aic3262_ops_reg_write(struct snd_soc_component *codec, unsigned int reg,
    +			  unsigned char val)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_reg_write(aic3262->control_data,
    +					aic3262_ops_cfw2reg(reg), val);
    +}
    +
    +static int aic3262_ops_set_bits(struct snd_soc_component *codec, unsigned int reg,
    +				unsigned char mask, unsigned char val)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_set_bits(aic3262->control_data,
    +					aic3262_ops_cfw2reg(reg), mask, val);
    +
    +}
    +
    +static int aic3262_ops_bulk_read(struct snd_soc_component *codec, unsigned int reg,
    +				 int count, u8 *buf)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_bulk_read(aic3262->control_data,
    +					aic3262_ops_cfw2reg(reg), count, buf);
    +}
    +
    +static int aic3262_ops_bulk_write(struct snd_soc_component *codec, unsigned int reg,
    +			   int count, const u8 *buf)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	return aic3xxx_bulk_write(aic3262->control_data,
    +					aic3262_ops_cfw2reg(reg), count, buf);
    +}
    +
    +/**
    + * aic3262_ops_lock_lock: To Read the run state of the DAC and ADC
    + *			by reading the codec and returning the run state
    + * @pv: pointer argument to the codec
    + *
    + * Run state Bit format
    + *
    + * ------------------------------------------------------
    + * D31|..........| D7 | D6|  D5  |  D4  | D3 | D2 | D1  |   D0  |
    + * R               R    R   LADC   RADC    R    R   LDAC   RDAC
    + * ------------------------------------------------------
    + *
    + * R- Reserved
    + * LDAC- Left DAC
    + * RDAC- Right DAC
    + *
    + * Return value  : Integer
    + */
    +static int aic3262_ops_lock(struct snd_soc_component *codec)
    +{
    +	mutex_lock(&codec->io_mutex);
    +	/* Reading the run state of adc and dac */
    +	return aic3262_get_runstate(codec);
    +
    +}
    +
    +/**
    + * aic3262_ops_dlock_unlock: To unlock the mutex acqiured for reading
    + *			run state of the codec
    + * @pv: pointer argument to the codec
    + *
    + * Return Value: integer returning 0
    + */
    +static int aic3262_ops_unlock(struct snd_soc_component *codec)
    +{
    +	/*Releasing the lock of mutex */
    +	mutex_unlock(&codec->io_mutex);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_ops_dlock_stop:
    + * @pv: pointer Argument to the codec
    + * @mask: tells us the bit format of the codec running state
    + *
    + * Bit Format:
    + * ------------------------------------------------------
    + * D31|..........| D7 | D6| D5 | D4 | D3 | D2 | D1 | D0 |
    + * R               R    R   AL   AR    R    R   DL   DR
    + * ------------------------------------------------------
    + * R  - Reserved
    + * A  - minidsp_A
    + * D  - minidsp_D
    + *
    + * Return: return run state
    + */
    +static int aic3262_ops_stop(struct snd_soc_component *codec, int mask)
    +{
    +	int run_state = 0;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	run_state = aic3262_get_runstate(codec);
    +
    +	if (mask & AIC3XXX_COPS_MDSP_A)
    +		aic3xxx_set_bits(aic3262->control_data,
    +				 AIC3262_ADC_DATAPATH_SETUP, 0xC0, 0);
    +
    +	if (mask & AIC3XXX_COPS_MDSP_D)
    +		aic3xxx_set_bits(aic3262->control_data,
    +				 AIC3262_DAC_DATAPATH_SETUP, 0xC0, 0);
    +
    +	if ((mask & AIC3XXX_COPS_MDSP_A) &&
    +		!aic3xxx_wait_bits(aic3262->control_data,
    +				      AIC3262_ADC_FLAG, AIC3262_ADC_POWER_MASK,
    +				      0, AIC326X_TIME_DELAY,
    +				      AIC326X_DELAY_COUNTER))
    +		goto err;
    +
    +	if ((mask & AIC3XXX_COPS_MDSP_D) &&
    +		!aic3xxx_wait_bits(aic3262->control_data,
    +				      AIC3262_DAC_FLAG, AIC3262_DAC_POWER_MASK,
    +				      0, AIC326X_TIME_DELAY,
    +				      AIC326X_DELAY_COUNTER))
    +		goto err;
    +
    +	return run_state;
    +err:
    +	dev_err(codec->dev, "Unable to turn off ADCs or DACs at [%s:%d]",
    +				__FILE__, __LINE__);
    +	return -EINVAL;
    +}
    +
    +/**
    + * aic3262_ops_lock_restore: To unlock the mutex acqiured for reading
    + * @pv: pointer argument to the codec,run_state
    + * @run_state:  run state of the codec and to restore the states of the dsp
    + *
    + * Return Value	: integer returning 0
    + */
    +
    +static int aic3262_ops_restore(struct snd_soc_component *codec, int run_state)
    +{
    +	int sync_state;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	/* This is for read the sync mode register state  */
    +	sync_state = aic3xxx_reg_read(aic3262->control_data, AIC3262_DAC_PRB);
    +
    +	/*checking whether the sync mode has been set or
    +	   not and checking the current state */
    +	if (((run_state & 0x30) && (run_state & 0x03))&& (sync_state & 0x80))
    +		aic3262_restart_dsps_sync(codec, run_state);
    +	else
    +		aic3262_dsp_pwrup(codec, run_state);
    +
    +	return 0;
    +}
    +
    +/**
    + * aic3262_ops_adaptivebuffer_swap: To swap the coefficient buffers
    + *				 of minidsp according to mask
    + * @pv: pointer argument to the codec,
    + * @mask: tells us which dsp has to be chosen for swapping
    + *
    + * Return Value    : returning 0 on success
    + */
    +static int aic3262_ops_adaptivebuffer_swap(struct snd_soc_component *codec, int mask)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	const int sbuf[][2] = {
    +		{ AIC3XXX_ABUF_MDSP_A, AIC3262_ADC_ADAPTIVE_CRAM_REG },
    +		{ AIC3XXX_ABUF_MDSP_D1, AIC3262_DAC_ADAPTIVE_BANK1_REG },
    +		{ AIC3XXX_ABUF_MDSP_D2, AIC3262_DAC_ADAPTIVE_BANK2_REG },
    +	};
    +	int i;
    +
    +	for (i = 0; i < sizeof(sbuf)/sizeof(sbuf[0]); ++i) {
    +		if ((mask & sbuf[i][0])) {
    +			aic3xxx_set_bits(aic3262->control_data, sbuf[i][1],
    +					0x1, 0x1);
    +			if (!aic3xxx_wait_bits(aic3262->control_data,
    +						sbuf[i][1], 0x1, 0, 5, 1)) {
    +			dev_err(codec->dev, "miniDSP buffer swap failure");
    +			return -EINVAL;
    +			}
    +		}
    +	}
    +		return 0;
    +}
    +
    +/**
    + * get_runstate: To read the current state of the dac's and adc's
    + * @ps: pointer argument to the codec
    + *
    + * Return Value	: returning the runstate
    + */
    +static int aic3262_get_runstate(struct snd_soc_component *codec)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	unsigned int dac, adc;
    +	/* Read the run state */
    +	dac = aic3xxx_reg_read(aic3262->control_data, AIC3262_DAC_FLAG);
    +	adc = aic3xxx_reg_read(aic3262->control_data, AIC3262_ADC_FLAG);
    +
    +	return (((adc>>6)&1)<<5)  |
    +		(((adc>>2)&1)<<4) |
    +		(((dac>>7)&1)<<1) |
    +		(((dac>>3)&1)<<0);
    +}
    +
    +/**
    + * aic3262_dsp_pwrdwn_status: To read the status of dsp's
    + * @pv: pointer argument to the codec , cur_state of dac's and adc's
    + *
    + * Return Value	: integer returning 0
    + */
    +static int aic3262_dsp_pwrdwn_status(struct snd_soc_component *codec)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	aic3xxx_set_bits(aic3262->control_data,
    +			AIC3262_ADC_DATAPATH_SETUP, 0XC0, 0);
    +	aic3xxx_set_bits(aic3262->control_data,
    +			AIC3262_DAC_DATAPATH_SETUP, 0XC0, 0);
    +
    +	if (!aic3xxx_wait_bits(aic3262->control_data, AIC3262_ADC_FLAG,
    +			      AIC3262_ADC_POWER_MASK, 0, AIC326X_TIME_DELAY,
    +			      AIC326X_DELAY_COUNTER))
    +		goto err;
    +	if (!aic3xxx_wait_bits(aic3262->control_data, AIC3262_DAC_FLAG,
    +			      AIC3262_DAC_POWER_MASK, 0, AIC326X_TIME_DELAY,
    +			      AIC326X_DELAY_COUNTER))
    +		goto err;
    +
    +	return 0;
    +err:
    +	dev_err(codec->dev, "DAC/ADC Power down timedout at [%s:%d]",
    +				__FILE__, __LINE__);
    +	return -EINVAL;
    +}
    +static int aic3262_dsp_pwrup(struct snd_soc_component *codec, int state)
    +{
    +	int adc_reg_mask = 0;
    +	int adc_power_mask = 0;
    +	int dac_reg_mask = 0;
    +	int dac_power_mask = 0;
    +	int ret_wbits;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	if (state & AIC3XXX_COPS_MDSP_A_L) {
    +		adc_reg_mask |= 0x80;
    +		adc_power_mask |= AIC3262_LADC_POWER_MASK;
    +	}
    +	if (state & AIC3XXX_COPS_MDSP_A_R) {
    +		adc_reg_mask |= 0x40;
    +		adc_power_mask |= AIC3262_RADC_POWER_MASK;
    +	}
    +
    +	if (state & AIC3XXX_COPS_MDSP_A)
    +		aic3xxx_set_bits(aic3262->control_data,
    +					AIC3262_ADC_DATAPATH_SETUP, 0XC0,
    +					adc_reg_mask);
    +
    +	if (state & AIC3XXX_COPS_MDSP_D_L) {
    +		dac_reg_mask |= 0x80;
    +		dac_power_mask |= AIC3262_LDAC_POWER_STATUS_MASK;
    +	}
    +	if (state & AIC3XXX_COPS_MDSP_D_R) {
    +		dac_reg_mask |= 0x40;
    +		dac_power_mask |= AIC3262_RDAC_POWER_STATUS_MASK;
    +	}
    +
    +	if (state & AIC3XXX_COPS_MDSP_D)
    +		aic3xxx_set_bits(aic3262->control_data,
    +					AIC3262_DAC_DATAPATH_SETUP, 0XC0,
    +					dac_reg_mask);
    +
    +	if (state & AIC3XXX_COPS_MDSP_A) {
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +				AIC3262_ADC_FLAG, AIC3262_ADC_POWER_MASK,
    +				adc_power_mask, AIC326X_TIME_DELAY,
    +				AIC326X_DELAY_COUNTER);
    +		if (!ret_wbits)
    +			dev_err(codec->dev, "ADC Power down timedout\n");
    +	}
    +
    +	if (state & AIC3XXX_COPS_MDSP_D) {
    +		ret_wbits = aic3xxx_wait_bits(aic3262->control_data,
    +				AIC3262_DAC_FLAG, AIC3262_DAC_POWER_MASK,
    +				dac_power_mask, AIC326X_TIME_DELAY,
    +				AIC326X_DELAY_COUNTER);
    +		if (!ret_wbits)
    +			dev_err(codec->dev, "ADC Power down timedout\n");
    +	}
    +
    +	return 0;
    +}
    +
    +static int aic3262_restart_dsps_sync(struct snd_soc_component *codec, int run_state)
    +{
    +
    +	aic3262_dsp_pwrdwn_status(codec);
    +	aic3262_dsp_pwrup(codec, run_state);
    +
    +	return 0;
    +}
    +
    +static const struct aic3xxx_codec_ops aic3262_cfw_codec_ops = {
    +	.reg_read  =	aic3262_ops_reg_read,
    +	.reg_write =	aic3262_ops_reg_write,
    +	.set_bits  =	aic3262_ops_set_bits,
    +	.bulk_read =	aic3262_ops_bulk_read,
    +	.bulk_write =	aic3262_ops_bulk_write,
    +	.lock      =	aic3262_ops_lock,
    +	.unlock    =	aic3262_ops_unlock,
    +	.stop      =	aic3262_ops_stop,
    +	.restore   =	aic3262_ops_restore,
    +	.bswap     =	aic3262_ops_adaptivebuffer_swap,
    +};
    +
    +
    +/**
    + * aic3262_codec_read: provide read api to read aic3262 registe space
    + * @codec: pointer variable to codec having codec information,
    + * @reg: register address,
    + *
    + * Return: Return value will be value read.
    + */
    +static unsigned int aic3262_codec_read(struct snd_soc_component *codec, unsigned int reg)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	u8 value;
    +
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +	value = aic3xxx_reg_read(aic3262->control_data, reg);
    +	dev_dbg(codec->dev, "p %d , r 30 %x %x\n",
    +		aic_reg->aic3xxx_register.page,
    +		aic_reg->aic3xxx_register.offset, value);
    +	return value;
    +}
    +
    +/**
    + * aic3262_codec_write: provide write api to write at aic3262 registe space
    + * @codec: Pointer variable to codec having codec information,
    + * @reg: Register address,
    + * @value: Value to be written to address space
    + *
    + * Return: Total no of byte written to address space.
    + */
    +static int aic3262_codec_write(struct snd_soc_component *codec, unsigned int reg,
    +			unsigned int value)
    +{
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) ®
    +
    +	dev_dbg(codec->dev, "p %d, w 30 %x %x\n",
    +		aic_reg->aic3xxx_register.page,
    +		aic_reg->aic3xxx_register.offset, value);
    +	return aic3xxx_reg_write(aic3262->control_data, reg, value);
    +}
    +
    +/**
    + * aic3262_set_interface_fmt: Setting interface ASI1/2/3 data format
    + * @dai: ponter to dai Holds runtime data for a DAI,
    + * @fmt: asi format info,
    + * @channel: number of channel,
    + *
    + * Return: On success return 0.
    +*/
    +static int aic3262_set_interface_fmt(struct snd_soc_dai *dai, unsigned int fmt,
    +					unsigned int channel)
    +{
    +	int aif_interface_reg;
    +	int aif_bclk_offset_reg;
    +	struct snd_soc_component *codec = dai->component;
    +	u8 iface_val = 0;
    +	u8 dsp_a_val = 0;
    +
    +	switch (dai->id) {
    +	case 0:
    +		aif_interface_reg = AIC3262_ASI1_BUS_FMT;
    +		aif_bclk_offset_reg = AIC3262_ASI1_LCH_OFFSET;
    +		break;
    +	case 1:
    +		aif_interface_reg = AIC3262_ASI2_BUS_FMT;
    +		aif_bclk_offset_reg = AIC3262_ASI2_LCH_OFFSET;
    +		break;
    +	case 2:
    +		aif_interface_reg = AIC3262_ASI3_BUS_FMT;
    +		aif_bclk_offset_reg = AIC3262_ASI3_LCH_OFFSET;
    +		break;
    +	default:
    +		return -EINVAL;
    +
    +	}
    +	/* interface format */
    +	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    +	case SND_SOC_DAIFMT_I2S:
    +		iface_val = 0;
    +		break;
    +	case SND_SOC_DAIFMT_DSP_A:
    +		dsp_a_val = 0x1;	/* Intentionally falling through */
    +		fallthrough;
    +	case SND_SOC_DAIFMT_DSP_B:
    +		if (channel == 1)
    +			iface_val = 0x80;	/* Choose mono PCM */
    +		else if (channel <= 8)
    +			iface_val = 0x20;	/* choose multichannel PCM */
    +		else
    +			return -EINVAL;
    +		break;
    +	case SND_SOC_DAIFMT_RIGHT_J:
    +		iface_val = 0x40;
    +		break;
    +	case SND_SOC_DAIFMT_LEFT_J:
    +		iface_val = 0x60;
    +		break;
    +	default:
    +		dev_err(codec->dev, "Invalid DAI interface format\n");
    +		return -EINVAL;
    +	}
    +	snd_soc_component_update_bits(codec, aif_interface_reg,
    +					AIC3262_ASI_INTERFACE_MASK, iface_val);
    +	snd_soc_component_update_bits(codec, aif_bclk_offset_reg,
    +					AIC3262_BCLK_OFFSET_MASK, dsp_a_val);
    +	return 0;
    +
    +}
    +
    +/**
    + * aic3262_hw_params: This function is to set the hardware parameters
    + *		for AIC3262.
    + *		The functions set the sample rate and audio serial data word
    + *		length.
    + * @substream: pointer variable to sn_pcm_substream,
    + * @params: pointer to snd_pcm_hw_params structure,
    + * @dai: ponter to dai Holds runtime data for a DAI,
    + *
    + * Return: Return 0 on success.
    + */
    +int aic3262_hw_params(struct snd_pcm_substream *substream,
    +			struct snd_pcm_hw_params *params,
    +			struct snd_soc_dai *dai)
    +{
    +	struct snd_soc_component *codec = dai->component;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	int asi_reg, ret = 0;
    +	u8 data = 0, value = 0, val = 0, wclk_div = 0, bclk_div = 0;
    +	unsigned int channels = params_channels(params);
    +
    +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    +		aic3262->stream_status = 1;
    +	else
    +		aic3262->stream_status = 0;
    +
    +	switch (dai->id) {
    +	case 0:
    +		asi_reg = AIC3262_ASI1_BUS_FMT;
    +		break;
    +	case 1:
    +		asi_reg = AIC3262_ASI2_BUS_FMT;
    +		break;
    +	case 2:
    +		asi_reg = AIC3262_ASI3_BUS_FMT;
    +		break;
    +	default:
    +		return -EINVAL;
    +	}
    +
    +	switch (params_format(params)) {
    +	case SNDRV_PCM_FORMAT_S16_LE:
    +		data = data | 0x00;
    +		break;
    +	case SNDRV_PCM_FORMAT_S20_3LE:
    +		data |= (0x08);
    +		break;
    +	case SNDRV_PCM_FORMAT_S24_LE:
    +		data |= (0x10);
    +		break;
    +	case SNDRV_PCM_FORMAT_S32_LE:
    +		data |= (0x18);
    +		break;
    +	}
    +
    +	/* Configure TDM for multi chennels */
    +	switch (channels) {
    +	case 4:
    +		value = value | 0x40;
    +		bclk_div = 0x03;
    +		wclk_div = 0x40;
    +		break;
    +	case 6:
    +		bclk_div = 0x02;
    +		wclk_div = 0x60;
    +		value = value | 0x80;
    +		break;
    +	case 8:
    +		bclk_div = 0x01;
    +		wclk_div = 0x00;
    +		value = value | 0xC0;
    +		break;
    +	default:
    +		bclk_div = 0x04;
    +		wclk_div = 0x20;
    +	}
    +
    +	snd_soc_component_update_bits(codec, AIC3262_ASI1_CHNL_SETUP,
    +				AIC3262_ASI1_CHNL_MASK, value);
    +
    +	snd_soc_component_update_bits(codec, AIC3262_ASI1_BCLK_N,
    +				AIC3262_ASI1_BCLK_N_MASK, bclk_div);
    +
    +	snd_soc_component_update_bits(codec, AIC3262_ASI1_WCLK_N,
    +				AIC3262_ASI1_WCLK_N_MASK, wclk_div);
    +
    +
    +	val = snd_soc_component_read(codec, AIC3262_ASI1_BUS_FMT);
    +	val = snd_soc_component_read(codec, AIC3262_ASI1_CHNL_SETUP);
    +
    +	/* configure the respective Registers for the above configuration */
    +	snd_soc_component_update_bits(codec, asi_reg,
    +			    AIC3262_ASI_DATA_WORD_LENGTH_MASK, data);
    +	ret = aic3262_set_interface_fmt(dai, aic3262->asi_fmt[dai->id],
    +					 channels);
    +	if (ret < 0) {
    +		dev_err(codec->dev, "failed to set hardware params for AIC3262\n");
    +		return ret;
    +	}
    +
    +	return 0;
    +}
    +
    +/**
    + * aic3262_mute: This function is to mute or unmute the left and right DAC
    + * @dai: ponter to dai Holds runtime data for a DAI,
    + * @mute: integer value one if we using mute else unmute,
    + *
    + * Return: return 0 on success.
    + */
    +static int aic3262_mute(struct snd_soc_dai *dai, int mute, int stream)
    +{
    +	struct snd_soc_component *codec = dai->component;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	dev_dbg(codec->dev, "codec : %s : started\n", __func__);
    +	if (dai->id > 2)
    +		return -EINVAL;
    +	if (mute) {
    +		aic3262->mute_asi &= ~((0x1) << dai->id);
    +		if (aic3262->mute_asi == 0)
    +			/* Mute only when all asi's are muted */
    +			snd_soc_component_update_bits(codec,
    +						   AIC3262_DAC_MVOL_CONF,
    +						   AIC3262_DAC_LR_MUTE_MASK,
    +						   AIC3262_DAC_LR_MUTE);
    +
    +	} else {	/* Unmute */
    +		if (aic3262->mute_asi == 0)
    +			/* Unmute for the first asi that need to unmute.
    +			   rest unmute will pass */
    +			snd_soc_component_update_bits(codec,
    +						   AIC3262_DAC_MVOL_CONF,
    +						   AIC3262_DAC_LR_MUTE_MASK,
    +						   0x0);
    +		aic3262->mute_asi |= ((0x1) << dai->id);
    +	}
    +	dev_dbg(codec->dev, "codec : %s : ended\n", __func__);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_set_dai_fmt: This function is to set the DAI format
    + * @codec_dai: ponter to dai Holds runtime data for a DAI,
    + * @fmt: asi format info,
    + *
    + * return: return 0 on success.
    + */
    +static int aic3262_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
    +{
    +	struct aic3262_priv *aic3262;
    +	struct snd_soc_component *codec;
    +	u8 iface_val, master;
    +	int aif_bclk_wclk_reg;
    +
    +	codec = codec_dai->component;
    +	aic3262 = snd_soc_component_get_drvdata(codec);
    +	iface_val = 0x00;
    +	master = 0x0;
    +
    +	switch (codec_dai->id) {
    +	case 0:
    +		aif_bclk_wclk_reg = AIC3262_ASI1_BWCLK_CNTL_REG;
    +		break;
    +	case 1:
    +		aif_bclk_wclk_reg = AIC3262_ASI2_BWCLK_CNTL_REG;
    +		break;
    +	case 2:
    +		aif_bclk_wclk_reg = AIC3262_ASI3_BWCLK_CNTL_REG;
    +		break;
    +	default:
    +		return -EINVAL;
    +
    +	}
    +	aic3262->asi_fmt[codec_dai->id] = fmt;
    +	/* set master/slave audio interface */
    +	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
    +	case SND_SOC_DAIFMT_CBP_CFP:
    +		aic3262->master = 1;
    +		master |= (AIC3262_WCLK_OUT_MASK | AIC3262_BCLK_OUT_MASK);
    +		break;
    +	case SND_SOC_DAIFMT_CBC_CFC:
    +		aic3262->master = 0;
    +		break;
    +	case SND_SOC_DAIFMT_CBC_CFP:	/* new case..for debug purpose */
    +		master |= (AIC3262_WCLK_OUT_MASK);
    +		aic3262->master = 0;
    +		break;
    +	case SND_SOC_DAIFMT_CBP_CFC:
    +		master |= (AIC3262_BCLK_OUT_MASK);
    +		aic3262->master = 0;
    +		break;
    +
    +	default:
    +		dev_err(codec->dev, "Invalid DAI master/slave" " interface\n");
    +
    +		return -EINVAL;
    +	}
    +	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    +	case SND_SOC_DAIFMT_DSP_A:
    +	case SND_SOC_DAIFMT_DSP_B:
    +		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    +		case SND_SOC_DAIFMT_NB_NF:
    +			break;
    +		case SND_SOC_DAIFMT_IB_NF:
    +			master |= AIC3262_BCLK_INV_MASK;
    +			break;
    +		default:
    +			return -EINVAL;
    +		}
    +		break;
    +	case SND_SOC_DAIFMT_I2S:
    +	case SND_SOC_DAIFMT_RIGHT_J:
    +	case SND_SOC_DAIFMT_LEFT_J:
    +		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    +		case SND_SOC_DAIFMT_NB_NF:
    +			break;
    +		case SND_SOC_DAIFMT_IB_NF:
    +			master |= AIC3262_BCLK_INV_MASK;
    +			break;
    +		default:
    +			return -EINVAL;
    +		}
    +		break;
    +	default:
    +		return -EINVAL;
    +	}
    +	snd_soc_component_update_bits(codec, aif_bclk_wclk_reg,
    +			    AIC3262_WCLK_BCLK_MASTER_MASK, master);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_dai_set_pll: This function is to Set pll for aic3262 codec dai
    + * @dai: ponter to dai Holds runtime data for a DAI,$
    + * @pll_id: integer pll_id
    + * @source: DAI specific source for the PLL
    + * @fin: PLL Input clock frequency in Hz,
    + * @fout: Frequency out,
    + *
    + * Return: return 0 on success
    +*/
    +static int aic3262_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
    +				unsigned int Fin, unsigned int Fout)
    +{
    +	struct snd_soc_component *codec = dai->component;
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +
    +	dev_dbg(codec->dev, "In aic3262: dai_set_pll\n");
    +	dev_dbg(codec->dev, "%d, %s, dai->id = %d\n", __LINE__,
    +		__func__, dai->id);
    +	/* select the PLL_CLKIN */
    +	snd_soc_component_update_bits(codec, AIC3262_PLL_CLKIN_REG,
    +			    AIC3262_PLL_CLKIN_MASK, source <<
    +			    AIC3262_PLL_CLKIN_SHIFT);
    +	/* TODO: How to select low/high clock range? */
    +
    +	aic3xxx_cfw_set_pll(aic3262->cfw_p, dai->id);
    +
    +	return 0;
    +}
    +
    +/**
    + *
    + * aic3262_set_bias_level: This function is to get triggered
    + *			 when dapm events occurs.
    + * @codec: pointer variable to codec having informaton related to codec,
    + * @level: Bias level-> ON, PREPARE, STANDBY, OFF.
    + *
    + * Return: Return 0 on success.
    + */
    +static int aic3262_set_bias_level(struct snd_soc_component *codec,
    +				  enum snd_soc_bias_level level)
    +{
    +
    +	switch (level) {
    +		/* full On */
    +	case SND_SOC_BIAS_ON:
    +
    +		dev_dbg(codec->dev, "set_bias_on\n");
    +		break;
    +
    +		/* partial On */
    +	case SND_SOC_BIAS_PREPARE:
    +		dev_dbg(codec->dev, "set_bias_prepare\n");
    +		break;
    +
    +		/* Off, with power */
    +	case SND_SOC_BIAS_STANDBY:
    +		/*
    +		 * all power is driven by DAPM system,
    +		 * so output power is safe if bypass was set
    +		 */
    +		dev_dbg(codec->dev, "set_bias_stby\n");
    +		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
    +			pm_runtime_get_sync(codec->dev);
    +			snd_soc_component_update_bits(codec, AIC3262_POWER_CONF,
    +					    (AIC3262_AVDD_TO_DVDD_MASK |
    +					     AIC3262_EXT_ANALOG_SUPPLY_MASK),
    +					    0x0);
    +			snd_soc_component_update_bits(codec, AIC3262_REF_PWR_DLY,
    +					    AIC3262_CHIP_REF_PWR_ON_MASK,
    +					    AIC3262_CHIP_REF_PWR_ON);
    +			mdelay(40);
    +
    +			snd_soc_component_update_bits(codec, AIC3262_CHARGE_PUMP_CNTL,
    +				AIC3262_DYNAMIC_OFFSET_CALIB_MASK,
    +				AIC3262_DYNAMIC_OFFSET_CALIB);
    +		}
    +		break;
    +
    +		/* Off, without power */
    +	case SND_SOC_BIAS_OFF:
    +		dev_dbg(codec->dev, "set_bias_off\n");
    +		/* force all power off */
    +		if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
    +			snd_soc_component_update_bits(codec, AIC3262_REF_PWR_DLY,
    +					    AIC3262_CHIP_REF_PWR_ON_MASK, 0x0);
    +			snd_soc_component_update_bits(codec, AIC3262_POWER_CONF,
    +					    (AIC3262_AVDD_TO_DVDD_MASK |
    +					     AIC3262_EXT_ANALOG_SUPPLY_MASK),
    +					    (AIC3262_AVDD_TO_DVDD |
    +					     AIC3262_EXT_ANALOG_SUPPLY_OFF));
    +			pm_runtime_put(codec->dev);
    +		}
    +		break;
    +	}
    +
    +	codec->dapm.bias_level = level;
    +	return 0;
    +}
    +
    +/**
    + *
    + * aic3262_suspend; This function is to suspend the AIC3262 driver.
    + * @codec: pointer variable to codec having informaton related to codec,
    + *
    + * Return: Return 0 on success.
    + */
    +static int aic3262_suspend(struct snd_soc_component *codec)
    +{
    +	aic3262_set_bias_level(codec, SND_SOC_BIAS_OFF);
    +	return 0;
    +}
    +
    +/**
    + * aic3262_resume: This function is to resume the AIC3262 driver
    + *		 from off state to standby
    + * @codec: pointer variable to codec having informaton related to codec,
    + *
    + * Return: Return 0 on success.
    + */
    +static int aic3262_resume(struct snd_soc_component *codec)
    +{
    +	aic3262_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
    +
    +	return 0;
    +}
    +
    +/**
    + * aic3262_probe: This is first driver function called by the SoC core driver.
    + * @codec: pointer variable to codec having informaton related to codec,
    + *
    + * Return: Return 0 on success.
    + */
    +static int aic3262_codec_probe(struct snd_soc_component *codec)
    +{
    +	int ret = 0;
    +	struct aic3xxx *control;
    +	struct aic3262_priv *aic3262;
    +
    +	if (codec == NULL)
    +		dev_err(codec->dev, "codec pointer is NULL.\n");
    +
    +	control = dev_get_drvdata(codec->dev->parent);
    +	aic3262 = kzalloc(sizeof(struct aic3262_priv), GFP_KERNEL);
    +	if (aic3262 == NULL)
    +		return -ENOMEM;
    +
    +	aic3262->control_data = control;
    +	snd_soc_component_set_drvdata(codec, aic3262);
    +	aic3262->pdata = dev_get_platdata(codec->dev->parent);
    +	aic3262->codec = codec;
    +	aic3262->cur_fw = NULL;
    +	aic3262->cfw_p = &(aic3262->cfw_ps);
    +	aic3xxx_cfw_init(aic3262->cfw_p, &aic3262_cfw_codec_ops,
    +							aic3262->codec);
    +	aic3262->workqueue = create_singlethread_workqueue("aic3262-codec");
    +	if (!aic3262->workqueue) {
    +		ret = -ENOMEM;
    +		goto work_err;
    +	}
    +	INIT_DELAYED_WORK(&aic3262->delayed_work, aic3262_accessory_work);
    +	mutex_init(&aic3262->mutex);
    +	mutex_init(&codec->io_mutex);
    +	mutex_init(&aic3262->cfw_mutex);
    +	pm_runtime_enable(codec->dev);
    +	pm_runtime_resume(codec->dev);
    +		aic3262->dsp_runstate = 0;
    +
    +	if (control->irq) {
    +		ret = aic3xxx_request_irq(aic3262->control_data,
    +					  AIC3262_IRQ_HEADSET_DETECT,
    +					  aic3262_audio_handler,
    +					  IRQF_NO_SUSPEND,
    +					  "aic3262_irq_headset", codec);
    +
    +		if (ret) {
    +			dev_err(codec->dev,
    +				"HEADSET detect irq request failed:%d\n", ret);
    +			goto irq_err;
    +		} else {
    +
    +			/*  Dynamic Headset Detection Enabled */
    +
    +			snd_soc_component_update_bits(codec, AIC3262_HP_DETECT,
    +					AIC3262_HEADSET_IN_MASK,
    +					AIC3262_HEADSET_IN_MASK);
    +		}
    +	}
    +	/* Keep the reference voltage ON while in
    +	   STANDBY mode for fast power up */
    +
    +	snd_soc_component_update_bits(codec, AIC3262_REF_PWR_DLY,
    +			    AIC3262_CHIP_REF_PWR_ON_MASK,
    +			    AIC3262_CHIP_REF_PWR_ON);
    +	mdelay(40);
    +
    +	snd_soc_component_update_bits(codec, AIC3262_CHARGE_PUMP_CNTL,
    +				AIC3262_DYNAMIC_OFFSET_CALIB_MASK,
    +				AIC3262_DYNAMIC_OFFSET_CALIB);
    +
    +	aic3262_set_bias_level(codec, SND_SOC_BIAS_OFF);
    +
    +	aic3262->mute_asi = 0;
    +
    +	ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT,
    +				"tlv320aic3262_fw_v1.bin", codec->dev,
    +				GFP_KERNEL, codec, aic3262_firmware_load);
    +	if (ret < 0) {
    +		dev_err(codec->dev, "Firmware request failed\n");
    +		goto firm_err;
    +	}
    +
    +	return 0;
    +firm_err:
    +	aic3xxx_free_irq(control,
    +			 AIC3262_IRQ_HEADSET_DETECT, codec);
    +irq_err:
    +	destroy_workqueue(aic3262->workqueue);
    +work_err:
    +	kfree(aic3262);
    +	return 0;
    +}
    +
    +/*
    + * aic3262_remove: Cleans up and Remove aic3262 soc device
    + * @codec: pointer variable to codec having informaton related to codec,
    + *
    + * Return: Return 0 on success.
    + */
    +static void aic3262_codec_remove(struct snd_soc_component *codec)
    +{
    +	/* power down chip */
    +	struct aic3262_priv *aic3262 = snd_soc_component_get_drvdata(codec);
    +	struct aic3xxx *control = aic3262->control_data;
    +
    +	aic3262_set_bias_level(codec, SND_SOC_BIAS_OFF);
    +
    +	/* free_irq if any */
    +	switch (control->type) {
    +	case TLV320AIC3262:
    +		if (control->irq)
    +			aic3xxx_free_irq(control,
    +					 AIC3262_IRQ_HEADSET_DETECT, codec);
    +		break;
    +	default:
    +		dev_info(codec->dev, "Coded is not TLV320AIC3262\n");
    +	}
    +	/* release firmware if any */
    +	if (aic3262->cur_fw != NULL)
    +		release_firmware(aic3262->cur_fw);
    +	/* destroy workqueue for jac dev */
    +	destroy_workqueue(aic3262->workqueue);
    +
    +	kfree(aic3262);
    +}
    +
    +static struct snd_soc_component_driver soc_codec_driver_aic326x = {
    +	.probe = aic3262_codec_probe,
    +	.remove = aic3262_codec_remove,
    +	.suspend = aic3262_suspend,
    +	.resume = aic3262_resume,
    +	.read = aic3262_codec_read,
    +	.write = aic3262_codec_write,
    +	.controls = aic3262_snd_controls,
    +	.num_controls = ARRAY_SIZE(aic3262_snd_controls),
    +	.dapm_widgets = aic3262_dapm_widgets,
    +	.num_dapm_widgets = ARRAY_SIZE(aic3262_dapm_widgets),
    +	.dapm_routes = aic3262_dapm_routes,
    +	.num_dapm_routes = ARRAY_SIZE(aic3262_dapm_routes),
    +	.set_bias_level = aic3262_set_bias_level,
    +	//.reg_cache_size = 0,
    +	//.reg_word_size = sizeof(u8),
    +	//.reg_cache_default = NULL,
    +};
    +
    +static int aic326x_probe(struct platform_device *pdev)
    +{
    +	return snd_soc_register_component(&pdev->dev, &soc_codec_driver_aic326x,
    +					  aic326x_dai_driver,
    +					  ARRAY_SIZE(aic326x_dai_driver));
    +
    +}
    +
    +static int aic326x_remove(struct platform_device *pdev)
    +{
    +	snd_soc_unregister_component(&pdev->dev);
    +	return 0;
    +}
    +
    +static const struct of_device_id aic3262_of_match[] = {
    +		{ .compatible = "ti,aic3262", },
    +		{ .compatible = "ti,aic3268", },
    +		{ },
    +};
    +MODULE_DEVICE_TABLE(of, aic3262_of_match);
    +
    +static const struct platform_device_id aic3262_i2c_id[] = {
    +		{ "tlv320aic3262-codec", 0 },
    +		{ "tlv320aic3268-codec", 1 },
    +		{ }
    +};
    +MODULE_DEVICE_TABLE(i2c, aic3262_i2c_id);
    +
    +static struct platform_driver aic326x_codec_driver = {
    +	.driver = {
    +		.name = "tlv320aic3262-codec",
    +		.owner = THIS_MODULE,
    +		.of_match_table = aic3262_of_match,
    +	},
    +	.probe = aic326x_probe,
    +	.remove = aic326x_remove,
    +	.id_table = aic3262_i2c_id,
    +};
    +
    +module_platform_driver(aic326x_codec_driver);
    +
    +MODULE_ALIAS("platform:tlv320aic326x-codec");
    +MODULE_DESCRIPTION("ASoC TLV320AIC326X codec driver");
    +MODULE_AUTHOR("Y Preetam Sashank Reddy ");
    +MODULE_AUTHOR("Barani Prashanth ");
    +MODULE_AUTHOR("Mukund Navada K <navada@ti.com>");
    +MODULE_AUTHOR("Naren Vasanad <naren.vasanad@ti.com>");
    +MODULE_LICENSE("GPL");
    diff --git a/sound/soc/codecs/tlv320aic326x.h b/sound/soc/codecs/tlv320aic326x.h
    new file mode 100644
    index 000000000..b20bb447e
    --- /dev/null
    +++ b/sound/soc/codecs/tlv320aic326x.h
    @@ -0,0 +1,134 @@
    +/*
    + * linux/sound/soc/codecs/tlv320aic326x.h
    + *
    + * Copyright (C) 2011 TI Solutions Pvt Ltd.
    + *
    + * Based on sound/soc/codecs/tlv320aic3262.c
    + *
    + * This package is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2 as
    + * published by the Free Software Foundation.
    + *
    + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
    + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
    + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    + *
    + * The TLV320AIC3262 is a flexible, low-power, low-voltage stereo audio
    + * codec with digital microphone inputs and programmable outputs.
    + *
    + * History:
    + *
    + * Rev 0.1   ASoC driver support    TI         20-01-2011
    + *		The AIC325x ASoC driver is ported for the codec AIC3262.
    + * Rev 0.2   ASoC driver support    TI         21-03-2011
    + *		The AIC326x ASoC driver is updated for linux 2.6.32 Kernel.
    + * Rev 0.3   ASoC driver support    TI         20-04-2011
    + *		The AIC326x ASoC driver is ported to 2.6.35 omap4 kernel
    + */
    +
    +#ifndef _TLV320AIC3262_H
    +#define _TLV320AIC3262_H
    +#include "aic3xxx/aic3xxx_cfw.h"
    +#include "aic3xxx/aic3xxx_cfw_ops.h"
    +
    +#define AUDIO_NAME "aic3262"
    +#define AIC3262_VERSION "1.1"
    +/* Macro to enable the inclusion of tiload kernel driver */
    +#define AIC3262_TiLoad
    +#undef AIC3262_SYNC_MODE
    +#define AIC3262_ASI1_MASTER
    +#undef AIC3262_ASI2_MASTER
    +#undef AIC3262_ASI3_MASTER
    +/* Macro for McBsp master / slave configuration */
    +#define AIC3262_MCBSP_SLAVE	/*3262 master */
    +
    +/* Enable this macro allow for different ASI formats */
    +#undef ASI_MULTI_FMT
    +
    +/* Enable or disable controls to have Input routing*/
    +#undef FULL_IN_CNTL
    +/* AIC3262 supported sample rate are 8k to 192k */
    +#define AIC3262_RATES	SNDRV_PCM_RATE_8000_192000
    +
    +/* AIC3262 supports the word formats 16bits, 20bits, 24bits and 32 bits */
    +#define AIC3262_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
    +			 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
    +
    +#define AIC3262_FREQ_12000000 12000000
    +#define AIC3262_FREQ_19200000 19200000
    +#define AIC3262_FREQ_24000000 24000000
    +#define AIC3262_FREQ_38400000 38400000
    +/* Audio data word length = 16-bits (default setting) */
    +#define AIC3262_WORD_LEN_16BITS		0x00
    +#define AIC3262_WORD_LEN_20BITS		0x01
    +#define AIC3262_WORD_LEN_24BITS		0x02
    +#define AIC3262_WORD_LEN_32BITS		0x03
    +
    +/* sink: name of target widget */
    +#define AIC3262_WIDGET_NAME			0
    +/* control: mixer control name */
    +#define AIC3262_CONTROL_NAME			1
    +/* source: name of source name */
    +#define AIC3262_SOURCE_NAME			2
    +
    +/* D15..D8 aic3262 register offset */
    +#define AIC3262_REG_OFFSET_INDEX		0
    +/* D7...D0 register data */
    +#define AIC3262_REG_DATA_INDEX			1
    +
    +/* Serial data bus uses I2S mode (Default mode) */
    +#define AIC3262_I2S_MODE				0x00
    +#define AIC3262_DSP_MODE				0x01
    +#define AIC3262_RIGHT_JUSTIFIED_MODE			0x02
    +#define AIC3262_LEFT_JUSTIFIED_MODE			0x03
    +
    +/* 8 bit mask value */
    +#define AIC3262_8BITS_MASK				0xFF
    +
    +/* shift value for CLK_REG_3 register */
    +#define CLK_REG_3_SHIFT					6
    +/* shift value for DAC_OSR_MSB register */
    +#define DAC_OSR_MSB_SHIFT				4
    +
    +/* number of codec specific register for configuration */
    +#define NO_FEATURE_REGS				2
    +
    +/* AIC3262 register space */
    +/* Updated from 256 to support Page 3 registers */
    +#define	AIC3262_CACHEREGNUM				1024
    +
    +#define AIC326X_TIME_DELAY					5
    +#define AIC326X_DELAY_COUNTER					100
    +
    +struct aic3262_jack_data {
    +	struct snd_soc_jack *jack;
    +	int report;
    +};
    +
    +struct aic3262_priv {
    +	u32 sysclk;
    +	s32 master;
    +	u8 stream_status;
    +	struct aic3262_jack_data hs_jack;
    +	struct workqueue_struct *workqueue;
    +	struct delayed_work delayed_work;
    +	struct input_dev *idev;
    +	struct snd_soc_component *codec;
    +	struct mutex mutex;
    +	struct mutex cfw_mutex;
    +	struct cfw_state cfw_ps;
    +	struct cfw_state *cfw_p;
    +	struct aic3262_pdata *pdata;
    +	int mute_asi;	/* Bit 0 -> ASI1, Bit 1-> ASI2, Bit 2 -> ASI3 */
    +	int asi_fmt[2];
    +	int dsp_runstate;
    +	struct firmware *cur_fw;
    +	struct aic3xxx *control_data;
    +	int isdefault_fw;
    +};
    +
    +extern struct snd_soc_dai tlv320aic3262_dai;
    +void aic3262_hs_jack_detect(struct snd_soc_component *codec,
    +			    struct snd_soc_jack *jack, int report);
    +
    +#endif /* _TLV320AIC3262_H */
    -- 
    2.25.1
    
    

    I have build tested this following commands.

    make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- zImage
    make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- modules

    - Niranjan

  • Hi  ,

    I applied this patch successfully and removed the strange symbols like in patch 1. Then compiled and booted and the kernel. Still getting the same error below:-

    [   21.614501] platform sound0: deferred probe pending
    

    PFA the dmesg logs

    [    0.000000] Booting Linux on physical CPU 0x0
    [    0.000000] Linux version 6.1.119-00016-g12fce29825f6 (root@cdot-VirtualBox) (arm-oe-linux-gnueabi-gcc (GCC) 11.5.0, GNU ld (GNU Binutils) 2.38.20220708) #78 SMP PREEMPT Mon Sep  8 10:11:39 IST 2025
    [    0.000000] CPU: ARMv7 Processor [412fc0f2] revision 2 (ARMv7), cr=30c5387d
    [    0.000000] CPU: div instructions available: patching division code
    [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
    [    0.000000] OF: fdt: Machine model: TI AM5728 BeagleBoard-X15 rev C
    [    0.000000] Memory policy: Data cache writealloc
    [    0.000000] efi: UEFI not found.
    [    0.000000] Reserved memory: created CMA memory pool at 0x0000000095800000, size 56 MiB
    [    0.000000] OF: reserved mem: initialized node ipu2-memory@95800000, compatible id shared-dma-pool
    [    0.000000] Reserved memory: created CMA memory pool at 0x0000000099000000, size 64 MiB
    [    0.000000] OF: reserved mem: initialized node dsp1-memory@99000000, compatible id shared-dma-pool
    [    0.000000] Reserved memory: created DMA memory pool at 0x000000009d000000, size 32 MiB
    [    0.000000] OF: reserved mem: initialized node ipu1-memory@9d000000, compatible id shared-dma-pool
    [    0.000000] Reserved memory: created CMA memory pool at 0x000000009f000000, size 8 MiB
    [    0.000000] OF: reserved mem: initialized node dsp2-memory@9f000000, compatible id shared-dma-pool
    [    0.000000] cma: Reserved 64 MiB at 0x00000000ab800000
    [    0.000000] OMAP4: Map 0x00000000afd00000 to (ptrval) for dram barrier
    [    0.000000] Hit pending asynchronous external abort (FSR=0x00001211) during first unmask, this is most likely caused by a firmware/bootloader bug.
    [    0.000000] Zone ranges:
    [    0.000000]   DMA      [mem 0x0000000080000000-0x00000000afcfffff]
    [    0.000000]   Normal   empty
    [    0.000000]   HighMem  [mem 0x00000000afd00000-0x000000027fffffff]
    [    0.000000] Movable zone start for each node
    [    0.000000] Early memory node ranges
    [    0.000000]   node   0: [mem 0x0000000080000000-0x00000000956fffff]
    [    0.000000]   node   0: [mem 0x0000000095700000-0x00000000957fffff]
    [    0.000000]   node   0: [mem 0x0000000095800000-0x000000009cffffff]
    [    0.000000]   node   0: [mem 0x000000009d000000-0x000000009effffff]
    [    0.000000]   node   0: [mem 0x000000009f000000-0x00000000afcfffff]
    [    0.000000]   node   0: [mem 0x00000000b0000000-0x00000000feffffff]
    [    0.000000]   node   0: [mem 0x0000000200000000-0x000000027fffffff]
    [    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x000000027fffffff]
    [    0.000000] On node 0, zone HighMem: 768 pages in unavailable ranges
    [    0.000000] DRA752 ES2.0
    [    0.000000] clockdomain: ipu1_clkdm: powerdomain ipu_pwrdm does not exist
    [    0.000000] clockdomain: ipu_clkdm: powerdomain ipu_pwrdm does not exist
    [    0.000000] percpu: Embedded 16 pages/cpu s34324 r8192 d23020 u65536
    [    0.000000] pcpu-alloc: s34324 r8192 d23020 u65536 alloc=16*4096
    [    0.000000] pcpu-alloc: [0] 0 [0] 1 
    [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 1042182
    [    0.000000] Kernel command line: console=ttyS2,115200n8 root=PARTUUID=5c496148-02 rw rootfstype=ext4 rootwait
    [    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes, linear)
    [    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes, linear)
    [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
    [    0.000000] software IO TLB: area num 2.
    [    0.000000] software IO TLB: mapped [mem 0x00000000a3800000-0x00000000a7800000] (64MB)
    [    0.000000] Memory: 3758060K/4174848K available (12288K kernel code, 1469K rwdata, 3308K rodata, 2048K init, 308K bss, 220180K reserved, 196608K cma-reserved, 3325952K highmem)
    [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
    [    0.000000] trace event string verifier disabled
    [    0.000000] rcu: Preemptible hierarchical RCU implementation.
    [    0.000000] rcu: 	RCU event tracing is enabled.
    [    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=16 to nr_cpu_ids=2.
    [    0.000000] 	Trampoline variant of Tasks RCU enabled.
    [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
    [    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
    [    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
    [    0.000000] GIC: Using split EOI/Deactivate mode
    [    0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
    [    0.000000] OMAP clocksource: 32k_counter at 32768 Hz
    [    0.000000] clocksource: 32k_counter: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 58327039986419 ns
    [    0.000000] sched_clock: 32 bits at 33kHz, resolution 30517ns, wraps every 65535999984741ns
    [    0.001434] TI gptimer clockevent: always-on 32786 Hz at /ocp/interconnect@4ae00000/segment@10000/target-module@8000
    [    0.003143] TI gptimer percpu-dmtimer: 20000000 Hz at /ocp/interconnect@48800000/segment@0/target-module@2c000
    [    0.003326] TI gptimer percpu-dmtimer: 20000000 Hz at /ocp/interconnect@48800000/segment@0/target-module@2e000
    [    0.004211] Console: colour dummy device 80x30
    [    0.004272] Calibrating delay loop... 1993.93 BogoMIPS (lpj=9969664)
    [    0.062072] CPU: Testing write buffer coherency: ok
    [    0.062103] CPU0: Spectre v2: using ICIALLU workaround
    [    0.062103] CPU0: Spectre BHB: enabling loop workaround for all CPUs
    [    0.062103] pid_max: default: 32768 minimum: 301
    [    0.062255] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes, linear)
    [    0.062255] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes, linear)
    [    0.062896] /cpus/cpu@0 missing clock-frequency property
    [    0.062927] /cpus/cpu@1 missing clock-frequency property
    [    0.062927] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
    [    0.063568] cblist_init_generic: Setting adjustable number of callback queues.
    [    0.063568] cblist_init_generic: Setting shift to 1 and lim to 1.
    [    0.063690] Setting up static identity map for 0x80200000 - 0x80200138
    [    0.063781] rcu: Hierarchical SRCU implementation.
    [    0.063781] rcu: 	Max phase no-delay instances is 1000.
    [    0.065979] EFI services will not be available.
    [    0.066497] smp: Bringing up secondary CPUs ...
    [    0.126708] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
    [    0.126739] CPU1: Spectre v2: using ICIALLU workaround
    [    0.126831] smp: Brought up 1 node, 2 CPUs
    [    0.126861] SMP: Total of 2 processors activated (3994.41 BogoMIPS).
    [    0.126861] CPU: All CPU(s) started in HYP mode.
    [    0.126861] CPU: Virtualization extensions available.
    [    0.127288] devtmpfs: initialized
    [    0.150421] VFP support v0.3: implementor 41 architecture 4 part 30 variant f rev 0
    [    0.150604] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
    [    0.150604] futex hash table entries: 512 (order: 3, 32768 bytes, linear)
    [    0.155059] pinctrl core: initialized pinctrl subsystem
    [    0.155700] DMI not present or invalid.
    [    0.156127] NET: Registered PF_NETLINK/PF_ROUTE protocol family
    [    0.157928] DMA: preallocated 256 KiB pool for atomic coherent allocations
    [    0.158874] thermal_sys: Registered thermal governor 'step_wise'
    [    0.158905] cpuidle: using governor menu
    [    0.185211] platform ocp: Fixed dependency cycle(s) with /ocp/interconnect@4a000000/segment@0/target-module@8000/cm_core@0/clock@e00/clock@20
    [    0.185272] platform ocp: Fixed dependency cycle(s) with /ocp/interconnect@4a000000/segment@0/target-module@8000/cm_core@0/clock@700/clock@20
    [    0.188842] platform display: Fixed dependency cycle(s) with /ocp/target-module@58000000/dss@0
    [    0.190368] No ATAGs?
    [    0.190429] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers.
    [    0.190429] hw-breakpoint: maximum watchpoint size is 8 bytes.
    [    0.208587] reg-fixed-voltage fixedregulator-main_12v0: GPIO lookup for consumer (null)
    [    0.208587] reg-fixed-voltage fixedregulator-main_12v0: using device tree for GPIO lookup
    [    0.208618] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-main_12v0[0]'
    [    0.208618] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-main_12v0[0]'
    [    0.208648] reg-fixed-voltage fixedregulator-main_12v0: using lookup tables for GPIO lookup
    [    0.208648] reg-fixed-voltage fixedregulator-main_12v0: No GPIO consumer (null) found
    [    0.208892] reg-fixed-voltage fixedregulator-evm_5v0: GPIO lookup for consumer (null)
    [    0.208892] reg-fixed-voltage fixedregulator-evm_5v0: using device tree for GPIO lookup
    [    0.208923] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-evm_5v0[0]'
    [    0.208923] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-evm_5v0[0]'
    [    0.208953] reg-fixed-voltage fixedregulator-evm_5v0: using lookup tables for GPIO lookup
    [    0.208953] reg-fixed-voltage fixedregulator-evm_5v0: No GPIO consumer (null) found
    [    0.209564] iommu: Default domain type: Translated 
    [    0.209564] iommu: DMA domain TLB invalidation policy: strict mode 
    [    0.210906] SCSI subsystem initialized
    [    0.211059] libata version 3.00 loaded.
    [    0.211242] usbcore: registered new interface driver usbfs
    [    0.211273] usbcore: registered new interface driver hub
    [    0.211303] usbcore: registered new device driver usb
    [    0.211700] mc: Linux media interface: v0.10
    [    0.211730] pps_core: LinuxPPS API ver. 1 registered
    [    0.211761] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
    [    0.211761] PTP clock support registered
    [    0.211883] EDAC MC: Ver: 3.0.0
    [    0.213684] clocksource: Switched to clocksource 32k_counter
    [    0.221466] NET: Registered PF_INET protocol family
    [    0.221618] IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
    [    0.234191] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
    [    0.234222] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
    [    0.234222] TCP established hash table entries: 8192 (order: 3, 32768 bytes, linear)
    [    0.234283] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
    [    0.234527] TCP: Hash tables configured (established 8192 bind 8192)
    [    0.234588] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
    [    0.234619] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
    [    0.234741] NET: Registered PF_UNIX/PF_LOCAL protocol family
    [    0.235168] RPC: Registered named UNIX socket transport module.
    [    0.235168] RPC: Registered udp transport module.
    [    0.235168] RPC: Registered tcp transport module.
    [    0.235168] RPC: Registered tcp NFSv4.1 backchannel transport module.
    [    0.235198] PCI: CLS 0 bytes, default 64
    [    0.235565] armv7-pmu pmu: hw perfevents: no interrupt-affinity property, guessing.
    [    0.235717] hw perfevents: enabled with armv7_cortex_a15 PMU driver, 7 counters available
    [    0.236572] Initialise system trusted keyrings
    [    0.236938] workingset: timestamp_bits=30 max_order=20 bucket_order=0
    [    0.242309] squashfs: version 4.0 (2009/01/31) Phillip Lougher
    [    0.242919] NFS: Registering the id_resolver key type
    [    0.242950] Key type id_resolver registered
    [    0.242950] Key type id_legacy registered
    [    0.243011] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
    [    0.243041] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
    [    0.243041] ntfs: driver 2.1.32 [Flags: R/O].
    [    0.243530] Key type asymmetric registered
    [    0.243530] Asymmetric key parser 'x509' registered
    [    0.243652] bounce: pool size: 64 pages
    [    0.243804] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 246)
    [    0.243804] io scheduler mq-deadline registered
    [    0.243804] io scheduler kyber registered
    [    0.246887] omap_prm: probe of 4ae06500.prm failed with error -22
    [    0.292877] Serial: 8250/16550 driver, 5 ports, IRQ sharing enabled
    [    0.294860] STMicroelectronics ASC driver initialized
    [    0.295471] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4913, Function: panel_simple_init ****************************
    [    0.296844] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4918, Function: panel_simple_init ****************************
    [    0.296844] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4921, Function: panel_simple_init ****************************
    [    0.296844] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4924, Function: panel_simple_init ****************************
    [    0.296874] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4929, Function: panel_simple_init ****************************
    [    0.303955] brd: module loaded
    [    0.308563] loop: module loaded
    [    0.311767] mdio_bus fixed-0: GPIO lookup for consumer reset
    [    0.311767] mdio_bus fixed-0: using lookup tables for GPIO lookup
    [    0.311767] mdio_bus fixed-0: No GPIO consumer reset found
    [    0.312957] CAN device driver interface
    [    0.313323] e1000e: Intel(R) PRO/1000 Network Driver
    [    0.313323] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
    [    0.313385] igb: Intel(R) Gigabit Ethernet Network Driver
    [    0.313385] igb: Copyright (c) 2007-2014 Intel Corporation.
    [    0.314239] pegasus: Pegasus/Pegasus II USB Ethernet driver
    [    0.314270] usbcore: registered new interface driver pegasus
    [    0.314331] usbcore: registered new interface driver asix
    [    0.314361] usbcore: registered new interface driver ax88179_178a
    [    0.314392] usbcore: registered new interface driver cdc_ether
    [    0.314422] usbcore: registered new interface driver smsc75xx
    [    0.314453] usbcore: registered new interface driver smsc95xx
    [    0.314483] usbcore: registered new interface driver net1080
    [    0.314514] usbcore: registered new interface driver cdc_subset
    [    0.314544] usbcore: registered new interface driver zaurus
    [    0.314575] usbcore: registered new interface driver cdc_ncm
    [    0.315277] usbcore: registered new interface driver usb-storage
    [    0.316131] i2c_dev: i2c /dev entries driver
    [    0.318542] sdhci: Secure Digital Host Controller Interface driver
    [    0.318542] sdhci: Copyright(c) Pierre Ossman
    [    0.318725] Synopsys Designware Multimedia Card Interface Driver
    [    0.318939] sdhci-pltfm: SDHCI platform and OF driver helper
    [    0.319519] ledtrig-cpu: registered to indicate activity on CPUs
    [    0.319824] usbcore: registered new interface driver usbhid
    [    0.319824] usbhid: USB HID core driver
    [    0.322387] NET: Registered PF_INET6 protocol family
    [    0.323272] Segment Routing with IPv6
    [    0.323333] In-situ OAM (IOAM) with IPv6
    [    0.323394] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
    [    0.323913] NET: Registered PF_PACKET protocol family
    [    0.323913] can: controller area network core
    [    0.323974] NET: Registered PF_CAN protocol family
    [    0.323974] can: raw protocol
    [    0.323974] can: broadcast manager protocol
    [    0.324005] can: netlink gateway - max_hops=1
    [    0.324188] Key type dns_resolver registered
    [    0.324218] ThumbEE CPU extension supported.
    [    0.324249] Registering SWP/SWPB emulation handler
    [    0.324645] omap_voltage_late_init: Voltage driver support not added
    [    0.324645] Power Management for TI OMAP4+ devices.
    [    0.325408] Loading compiled-in X.509 certificates
    [    0.359008] platform 4a000000.interconnect: Fixed dependency cycle(s) with /ocp/interconnect@4a000000/segment@0/target-module@8000/cm_core@0/clock@d00/clock@20
    [    0.364990] pinctrl-single 4a003400.pinmux: 282 pins, size 1128
    [    0.387176] omap-dma-engine 4a056000.dma-controller: OMAP DMA engine driver (LinkedList1/2/3 supported)
    [    0.403198] gpio gpiochip0: (gpio-0-31): not an immutable chip, please consider fixing it!
    [    0.403350] gpio gpiochip0: (gpio-0-31): added GPIO chardev (254:0)
    [    0.403442] gpio gpiochip0: registered GPIOs 0 to 31 on gpio-0-31
    [    0.403472] OMAP GPIO hardware version 0.1
    [    0.405975] ti-sysc: probe of 4ae18000.target-module failed with error -16
    [    0.412902] printk: console [ttyS2] disabled
    [    0.412902] omap8250 48020000.serial: GPIO lookup for consumer rs485-term
    [    0.412933] omap8250 48020000.serial: using device tree for GPIO lookup
    [    0.412933] of_get_named_gpiod_flags: can't parse 'rs485-term-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@20000/serial@0[0]'
    [    0.412994] of_get_named_gpiod_flags: can't parse 'rs485-term-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@20000/serial@0[0]'
    [    0.413024] omap8250 48020000.serial: using lookup tables for GPIO lookup
    [    0.413055] omap8250 48020000.serial: No GPIO consumer rs485-term found
    [    0.413055] 48020000.serial: ttyS2 at MMIO 0x48020000 (irq = 100, base_baud = 3000000) is a 8250
    [    1.728729] printk: console [ttyS2] enabled
    [    1.740783] gpio gpiochip1: (gpio-32-63): not an immutable chip, please consider fixing it!
    [    1.749389] gpio gpiochip1: (gpio-32-63): added GPIO chardev (254:1)
    [    1.749450] gpio gpiochip1: registered GPIOs 32 to 63 on gpio-32-63
    [    1.750671] gpio gpiochip2: (gpio-64-95): not an immutable chip, please consider fixing it!
    [    1.759246] gpio gpiochip2: (gpio-64-95): added GPIO chardev (254:2)
    [    1.759338] gpio gpiochip2: registered GPIOs 64 to 95 on gpio-64-95
    [    1.760559] gpio gpiochip3: (gpio-96-127): not an immutable chip, please consider fixing it!
    [    1.769195] gpio gpiochip3: (gpio-96-127): added GPIO chardev (254:3)
    [    1.769256] gpio gpiochip3: registered GPIOs 96 to 127 on gpio-96-127
    [    1.770446] gpio gpiochip4: (gpio-128-159): not an immutable chip, please consider fixing it!
    [    1.779144] gpio gpiochip4: (gpio-128-159): added GPIO chardev (254:4)
    [    1.779235] gpio gpiochip4: registered GPIOs 128 to 159 on gpio-128-159
    [    1.780395] gpio gpiochip5: (gpio-160-191): not an immutable chip, please consider fixing it!
    [    1.789093] gpio gpiochip5: (gpio-160-191): added GPIO chardev (254:5)
    [    1.789184] gpio gpiochip5: registered GPIOs 160 to 191 on gpio-160-191
    [    1.790618] gpio gpiochip6: (gpio-192-223): not an immutable chip, please consider fixing it!
    [    1.799316] gpio gpiochip6: (gpio-192-223): added GPIO chardev (254:6)
    [    1.799377] gpio gpiochip6: registered GPIOs 192 to 223 on gpio-192-223
    [    1.800689] gpio gpiochip7: (gpio-224-255): not an immutable chip, please consider fixing it!
    [    1.809387] gpio gpiochip7: (gpio-224-255): added GPIO chardev (254:7)
    [    1.809478] gpio gpiochip7: registered GPIOs 224 to 255 on gpio-224-255
    [    1.811370] i2c i2c-2: GPIO lookup for consumer scl
    [    1.811370] i2c i2c-2: using device tree for GPIO lookup
    [    1.811401] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811431] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811462] i2c i2c-2: using lookup tables for GPIO lookup
    [    1.811462] i2c i2c-2: No GPIO consumer scl found
    [    1.811492] i2c i2c-2: GPIO lookup for consumer sda
    [    1.811492] i2c i2c-2: using device tree for GPIO lookup
    [    1.811523] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811553] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811584] i2c i2c-2: using lookup tables for GPIO lookup
    [    1.811584] i2c i2c-2: No GPIO consumer sda found
    [    1.812042] i2c 2-003c: Fixed dependency cycle(s) with /ocp/interconnect@48800000/target-module@190000/vip@0
    [    1.822174] omap_i2c 48060000.i2c: bus 2 rev0.12 at 400 kHz
    [    1.831481] omap8250 4806a000.serial: GPIO lookup for consumer rs485-term
    [    1.831481] omap8250 4806a000.serial: using device tree for GPIO lookup
    [    1.831512] of_get_named_gpiod_flags: can't parse 'rs485-term-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@6a000/serial@0[0]'
    [    1.831542] of_get_named_gpiod_flags: can't parse 'rs485-term-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@6a000/serial@0[0]'
    [    1.831573] omap8250 4806a000.serial: using lookup tables for GPIO lookup
    [    1.831573] omap8250 4806a000.serial: No GPIO consumer rs485-term found
    [    1.831604] 4806a000.serial: ttyS0 at MMIO 0x4806a000 (irq = 114, base_baud = 3000000) is a 8250
    [    1.843811] i2c i2c-0: GPIO lookup for consumer scl
    [    1.843841] i2c i2c-0: using device tree for GPIO lookup
    [    1.843841] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.843902] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.843933] i2c i2c-0: using lookup tables for GPIO lookup
    [    1.843933] i2c i2c-0: No GPIO consumer scl found
    [    1.843963] i2c i2c-0: GPIO lookup for consumer sda
    [    1.843963] i2c i2c-0: using device tree for GPIO lookup
    [    1.843963] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.843994] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.844024] i2c i2c-0: using lookup tables for GPIO lookup
    [    1.844055] i2c i2c-0: No GPIO consumer sda found
    [    1.844512] palmas 0-0058: Irq flag is 0x00000008
    [    1.877075] palmas 0-0058: Muxing GPIO 2b, PWM 0, LED 0
    [    1.907836] gpiochip_find_base: found new base at 504
    [    1.908020] gpio gpiochip8: (48070000.i2c:tps659038@58:tps659038_gpio): added GPIO chardev (254:8)
    [    1.908081] gpio gpiochip8: registered GPIOs 504 to 511 on 48070000.i2c:tps659038@58:tps659038_gpio
    [    1.909027] at24 0-0050: supply vcc not found, using dummy regulator
    [    1.915771] at24 0-0050: GPIO lookup for consumer wp
    [    1.915771] at24 0-0050: using device tree for GPIO lookup
    [    1.915802] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/eeprom@50[0]'
    [    1.915832] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/eeprom@50[0]'
    [    1.915893] at24 0-0050: using lookup tables for GPIO lookup
    [    1.915893] at24 0-0050: No GPIO consumer wp found
    [    1.916015] at24 0-0050: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
    [    1.923004] omap_i2c 48070000.i2c: bus 0 rev0.12 at 400 kHz
    [    1.930511] i2c i2c-1: GPIO lookup for consumer scl
    [    1.930541] i2c i2c-1: using device tree for GPIO lookup
    [    1.930541] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.930603] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.930633] i2c i2c-1: using lookup tables for GPIO lookup
    [    1.930633] i2c i2c-1: No GPIO consumer scl found
    [    1.930664] i2c i2c-1: GPIO lookup for consumer sda
    [    1.930664] i2c i2c-1: using device tree for GPIO lookup
    [    1.930664] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.930694] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.930755] i2c i2c-1: using lookup tables for GPIO lookup
    [    1.930755] i2c i2c-1: No GPIO consumer sda found
    [    1.931274] omap_i2c 48072000.i2c: bus 1 rev0.12 at 400 kHz
    [    1.939025] i2c i2c-3: GPIO lookup for consumer scl
    [    1.939025] i2c i2c-3: using device tree for GPIO lookup
    [    1.939056] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939086] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939117] i2c i2c-3: using lookup tables for GPIO lookup
    [    1.939117] i2c i2c-3: No GPIO consumer scl found
    [    1.939147] i2c i2c-3: GPIO lookup for consumer sda
    [    1.939147] i2c i2c-3: using device tree for GPIO lookup
    [    1.939147] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939208] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939239] i2c i2c-3: using lookup tables for GPIO lookup
    [    1.939239] i2c i2c-3: No GPIO consumer sda found
    [    1.939453] omap_i2c 4807a000.i2c: bus 3 rev0.12 at 400 kHz
    [    1.946594] i2c i2c-4: GPIO lookup for consumer scl
    [    1.946594] i2c i2c-4: using device tree for GPIO lookup
    [    1.946624] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.946655] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.946685] i2c i2c-4: using lookup tables for GPIO lookup
    [    1.946685] i2c i2c-4: No GPIO consumer scl found
    [    1.946716] i2c i2c-4: GPIO lookup for consumer sda
    [    1.946716] i2c i2c-4: using device tree for GPIO lookup
    [    1.946746] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.946777] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.946807] i2c i2c-4: using lookup tables for GPIO lookup
    [    1.946807] i2c i2c-4: No GPIO consumer sda found
    [    1.947082] omap_i2c 4807c000.i2c: bus 4 rev0.12 at 400 kHz
    [    1.947387] edt_ft5x06 4-0038: supply vcc not found, using dummy regulator
    [    1.957214] omap_rng 48090000.rng: Random Number Generator ver. 20
    [    1.959808] edt_ft5x06 4-0038: supply iovcc not found, using dummy regulator
    [    1.965942] random: crng init done
    [    1.973632] edt_ft5x06 4-0038: GPIO lookup for consumer reset
    [    1.976318] edt_ft5x06 4-0038: using device tree for GPIO lookup
    [    1.976348] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.976379] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.976440] edt_ft5x06 4-0038: using lookup tables for GPIO lookup
    [    1.976440] edt_ft5x06 4-0038: No GPIO consumer reset found
    [    1.976440] edt_ft5x06 4-0038: GPIO lookup for consumer wake
    [    1.976470] edt_ft5x06 4-0038: using device tree for GPIO lookup
    [    1.976470] of_get_named_gpiod_flags: can't parse 'wake-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.976501] of_get_named_gpiod_flags: can't parse 'wake-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.976562] edt_ft5x06 4-0038: using lookup tables for GPIO lookup
    [    1.976562] edt_ft5x06 4-0038: No GPIO consumer wake found
    [    2.000976] mdio_bus 48485000.mdio: GPIO lookup for consumer reset
    [    2.001007] mdio_bus 48485000.mdio: using device tree for GPIO lookup
    [    2.001007] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000[0]'
    [    2.001068] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000[0]'
    [    2.001098] mdio_bus 48485000.mdio: using lookup tables for GPIO lookup
    [    2.001098] mdio_bus 48485000.mdio: No GPIO consumer reset found
    [    2.005737] input: 4-0038 generic ft5x06 (8d) as /devices/platform/ocp/48000000.interconnect/48000000.interconnect:segment@0/4807c000.target-module/4807c000.i2c/i2c-4/4-0038/input/input0
    [    2.063720] davinci_mdio 48485000.mdio: davinci mdio revision 1.6, bus freq 1000000
    [    2.072235] mdio_bus 48485000.mdio:00: GPIO lookup for consumer reset
    [    2.072265] mdio_bus 48485000.mdio:00: using device tree for GPIO lookup
    [    2.072265] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@0[0]'
    [    2.072326] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@0[0]'
    [    2.072387] mdio_bus 48485000.mdio:00: using lookup tables for GPIO lookup
    [    2.072387] mdio_bus 48485000.mdio:00: No GPIO consumer reset found
    [    2.073242] mdio_bus 48485000.mdio:01: GPIO lookup for consumer reset
    [    2.073242] mdio_bus 48485000.mdio:01: using device tree for GPIO lookup
    [    2.073272] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@1[0]'
    [    2.073303] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@1[0]'
    [    2.073364] mdio_bus 48485000.mdio:01: using lookup tables for GPIO lookup
    [    2.073364] mdio_bus 48485000.mdio:01: No GPIO consumer reset found
    [    2.073547] davinci_mdio 48485000.mdio: phy[0]: device 48485000.mdio:00, driver unknown
    [    2.081634] davinci_mdio 48485000.mdio: phy[1]: device 48485000.mdio:01, driver unknown
    [    2.090270] cpsw-switch 48484000.switch: initialized cpsw ale version 1.4
    [    2.097106] cpsw-switch 48484000.switch: ALE Table size 1024
    [    2.102844] cpsw-switch 48484000.switch: cpts: overflow check period 500 (jiffies)
    [    2.110473] cpsw-switch 48484000.switch: CPTS: ref_clk_freq:266000000 calc_mult:4036623398 calc_shift:30 error:-1 nsec/sec
    [    2.121612] cpsw-switch 48484000.switch: Detected MACID = d0:03:eb:6c:3f:16
    [    2.128662] cpsw-switch 48484000.switch: Detected MACID = d0:03:eb:6c:3f:17
    [    2.137390] cpsw-switch 48484000.switch: initialized (regs 0x0000000048484000, pool size 256) hw_ver:0019010F 1.15 (0)
    [    2.159820] ti-sysc: probe of 4882c000.target-module failed with error -16
    [    2.167510] ti-sysc: probe of 4882e000.target-module failed with error -16
    [    2.178344] omap-mailbox 48840000.mailbox: omap mailbox rev 0x400
    [    2.185577] omap-mailbox 48842000.mailbox: omap mailbox rev 0x400
    [    2.200225] i2c 2-003c: Fixed dependency cycle(s) with /ocp/interconnect@48800000/target-module@190000/vip@0
    [    2.210205] platform 48990000.vip: Fixed dependency cycle(s) with /ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c
    [    2.226562] dra7-pcie 51000000.pcie: GPIO lookup for consumer (null)
    [    2.226562] dra7-pcie 51000000.pcie: using device tree for GPIO lookup
    [    2.226593] of_get_named_gpiod_flags: parsed 'gpios' property of node '/ocp/target-module@51000000/pcie@51000000[0]' - status (0)
    [    2.226654] gpio gpiochip3: Persistence not supported for GPIO 8
    [    2.226898] dra7-pcie 51000000.pcie: host bridge /ocp/target-module@51000000/pcie@51000000 ranges:
    [    2.235961] dra7-pcie 51000000.pcie:       IO 0x0020003000..0x0020012fff -> 0x0000000000
    [    2.244171] dra7-pcie 51000000.pcie:      MEM 0x0020013000..0x002fffffff -> 0x0020013000
    [    2.252532] dra7-pcie 51000000.pcie: iATU unroll: disabled
    [    2.258056] dra7-pcie 51000000.pcie: iATU regions: 16 ob, 4 ib, align 4K, limit 4G
    [    2.365844] dra7-pcie 51000000.pcie: PCIe Gen.2 x1 link up
    [    2.371459] dra7-pcie 51000000.pcie: PCI host bridge to bus 0000:00
    [    2.377807] pci_bus 0000:00: root bus resource [bus 00-ff]
    [    2.383331] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
    [    2.389556] pci_bus 0000:00: root bus resource [mem 0x20013000-0x2fffffff]
    [    2.396484] pci 0000:00:00.0: [104c:8888] type 01 class 0x060400
    [    2.402557] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
    [    2.408874] pci 0000:00:00.0: reg 0x14: [mem 0x00000000-0x0000ffff]
    [    2.415252] pci 0000:00:00.0: supports D1
    [    2.419281] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
    [    2.432189] PCI: bus0: Fast back to back transfers disabled
    [    2.437988] pci 0000:01:00.0: [8086:2526] type 00 class 0x028000
    [    2.444122] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00003fff 64bit]
    [    2.451293] pci 0000:01:00.0: PME# supported from D0 D3hot D3cold
    [    2.643829] PCI: bus1: Fast back to back transfers disabled
    [    2.649444] pci 0000:00:00.0: BAR 0: assigned [mem 0x20100000-0x201fffff]
    [    2.656311] pci 0000:00:00.0: BAR 8: assigned [mem 0x20200000-0x202fffff]
    [    2.663146] pci 0000:00:00.0: BAR 1: assigned [mem 0x20020000-0x2002ffff]
    [    2.669982] pci 0000:01:00.0: BAR 0: assigned [mem 0x20200000-0x20203fff 64bit]
    [    2.677368] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
    [    2.682647] pci 0000:00:00.0:   bridge window [mem 0x20200000-0x202fffff]
    [    2.689849] pcieport 0000:00:00.0: PME: Signaling with IRQ 138
    [    2.701782] edma 43300000.dma: memcpy is disabled
    [    2.709869] edma 43300000.dma: TI EDMA DMA engine driver
    [    2.721557] omap-iommu 40d01000.mmu: 40d01000.mmu registered
    [    2.729339] omap-iommu 40d02000.mmu: 40d02000.mmu registered
    [    2.736022] platform 40800000.dsp: Adding to iommu group 0
    [    2.743011] platform 58820000.ipu: Adding to iommu group 1
    [    2.748718] omap-iommu 58882000.mmu: 58882000.mmu registered
    [    2.756591] platform 55020000.ipu: Adding to iommu group 2
    [    2.762145] omap-iommu 55082000.mmu: 55082000.mmu registered
    [    2.774291] platform display: Fixed dependency cycle(s) with /ocp/target-module@58000000/dss@0
    [    2.783050] platform 58000000.dss: Fixed dependency cycle(s) with /display
    [    2.798858] omap-iommu 41501000.mmu: 41501000.mmu registered
    [    2.806152] omap-iommu 41502000.mmu: 41502000.mmu registered
    [    2.812988] platform 41000000.dsp: Adding to iommu group 3
    [    2.821014] ti-sysc 4ae06000.target-module: Failed to create device link (0x180) with ocp
    [    2.830871] gpio-clk clk_ov5640: GPIO lookup for consumer enable
    [    2.830871] gpio-clk clk_ov5640: using device tree for GPIO lookup
    [    2.830932] of_get_named_gpiod_flags: parsed 'enable-gpios' property of node '/clk_ov5640[0]' - status (0)
    [    2.830963] gpio gpiochip6: Persistence not supported for GPIO 18
    [    2.834838] reg-fixed-voltage fixedregulator-vdd_3v3: GPIO lookup for consumer (null)
    [    2.834838] reg-fixed-voltage fixedregulator-vdd_3v3: using device tree for GPIO lookup
    [    2.834899] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-vdd_3v3[0]'
    [    2.834899] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-vdd_3v3[0]'
    [    2.834930] reg-fixed-voltage fixedregulator-vdd_3v3: using lookup tables for GPIO lookup
    [    2.834930] reg-fixed-voltage fixedregulator-vdd_3v3: No GPIO consumer (null) found
    [    2.835357] reg-fixed-voltage fixedregulator-aic_dvdd: GPIO lookup for consumer (null)
    [    2.835388] reg-fixed-voltage fixedregulator-aic_dvdd: using device tree for GPIO lookup
    [    2.835388] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-aic_dvdd[0]'
    [    2.835418] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-aic_dvdd[0]'
    [    2.835418] reg-fixed-voltage fixedregulator-aic_dvdd: using lookup tables for GPIO lookup
    [    2.835418] reg-fixed-voltage fixedregulator-aic_dvdd: No GPIO consumer (null) found
    [    2.835662] reg-fixed-voltage fixedregulator-vtt: GPIO lookup for consumer (null)
    [    2.835662] reg-fixed-voltage fixedregulator-vtt: using device tree for GPIO lookup
    [    2.835693] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-vtt[0]'
    [    2.835693] of_get_named_gpiod_flags: parsed 'gpio' property of node '/fixedregulator-vtt[0]' - status (0)
    [    2.835723] gpio gpiochip1: Persistence not supported for GPIO 11
    [    2.865692] rtc-ds1307 2-006f: registered as rtc0
    [    2.870727] rtc-ds1307 2-006f: setting system clock to 2025-09-08T04:44:41 UTC (1757306681)
    [    2.879150] rtc-ds1307 2-006f: GPIO lookup for consumer wp
    [    2.879180] rtc-ds1307 2-006f: using device tree for GPIO lookup
    [    2.879180] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/rtc@6f[0]'
    [    2.879211] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/rtc@6f[0]'
    [    2.879272] rtc-ds1307 2-006f: using lookup tables for GPIO lookup
    [    2.879272] rtc-ds1307 2-006f: No GPIO consumer wp found
    [    2.882324] palmas-rtc 48070000.i2c:tps659038@58:tps659038_rtc: registered as rtc1
    [    2.891845] sdhci-omap 4809c000.mmc: GPIO lookup for consumer cd
    [    2.891845] sdhci-omap 4809c000.mmc: using device tree for GPIO lookup
    [    2.891876] of_get_named_gpiod_flags: parsed 'cd-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@9c000/mmc@0[0]' - status (0)
    [    2.891937] gpio gpiochip7: Persistence not supported for GPIO 27
    [    2.891967] omap_gpio 4805d000.gpio: Could not set line 27 debounce to 200000 microseconds (-22)
    [    2.893005] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 1147, Function: gpio_keys_init ****************************
    [    2.901367] sdhci-omap 480b4000.mmc: GPIO lookup for consumer wp
    [    2.913818] sdhci-omap 4809c000.mmc: Got CD GPIO
    [    2.913848] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 870, Function: gpio_keys_probe ****************************
    [    2.918487] sdhci-omap 480b4000.mmc: using device tree for GPIO lookup
    [    2.931396] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 788, Function: gpio_keys_get_devtree_pdata ****************************
    [    2.931457] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 523, Function: gpio_keys_setup_key ****************************
    [    2.945434] sdhci-omap 4809c000.mmc: GPIO lookup for consumer wp
    [    2.958709] of_get_named_gpiod_flags: parsed 'gpios' property of node '/gpio-keys/button-user1[0]' - status (0)
    [    2.958709] sdhci-omap 4809c000.mmc: using device tree for GPIO lookup
    [    2.958740] gpio gpiochip0: Persistence not supported for GPIO 14
    [    2.958740] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@9c000/mmc@0[0]'
    [    2.958831] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 523, Function: gpio_keys_setup_key ****************************
    [    2.958831] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@9c000/mmc@0[0]'
    [    2.972137] of_get_named_gpiod_flags: parsed 'gpios' property of node '/gpio-keys/button-user2[0]' - status (0)
    [    2.972167] gpio gpiochip3: Persistence not supported for GPIO 6
    [    2.972167] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@b4000/mmc@0[0]'
    [    2.972229] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 523, Function: gpio_keys_setup_key ****************************
    [    2.972229] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@b4000/mmc@0[0]'
    [    2.985534] of_get_named_gpiod_flags: parsed 'gpios' property of node '/gpio-keys/button-user3[0]' - status (0)
    [    2.985565] gpio gpiochip6: Persistence not supported for GPIO 1
    [    2.985595] sdhci-omap 4809c000.mmc: using lookup tables for GPIO lookup
    [    2.985595] sdhci-omap 4809c000.mmc: No GPIO consumer wp found
    [    2.985748] input: gpio-keys as /devices/platform/gpio-keys/input/input1
    [    2.986053] sdhci-omap 480b4000.mmc: using lookup tables for GPIO lookup
    [    2.992492] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 751, Function: gpio_keys_open ****************************
    [    2.992492] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 737, Function: gpio_keys_report_state ****************************
    [    2.992492] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 376, Function: gpio_keys_gpio_report_event ****************************
    [    3.005371] sdhci-omap 480b4000.mmc: No GPIO consumer wp found
    [    3.019226] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 376, Function: gpio_keys_gpio_report_event ****************************
    [    3.033020] sdhci-omap 480b4000.mmc: supply pbias not found, using dummy regulator
    [    3.046905] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 376, Function: gpio_keys_gpio_report_event ****************************
    [    3.068695] sdhci-omap 4809c000.mmc: no pinctrl state for ddr_3_3v mode
    [    3.076904] clk: Disabling unused clocks
    [    3.086212] l3init-clkctrl:0030:0: failed to disable
    [    3.104217] mmc1: SDHCI controller on 480b4000.mmc [480b4000.mmc] using ADMA
    [    3.116638] mmc0: SDHCI controller on 4809c000.mmc [4809c000.mmc] using ADMA
    [    3.124176] Waiting for root device PARTUUID=5c496148-02...
    [    3.163421] mmc0: new high speed SDHC card at address 5048
    [    3.169403] mmcblk0: mmc0:5048 SD32G 29.7 GiB 
    [    3.176635]  mmcblk0: p1 p2
    [    3.212707] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Quota mode: disabled.
    [    3.221710] VFS: Mounted root (ext4 filesystem) on device 179:2.
    [    3.235290] devtmpfs: mounted
    [    3.239624] Freeing unused kernel image (initmem) memory: 2048K
    [    3.245849] Run /sbin/init as init process
    [    3.250030]   with arguments:
    [    3.250061]     /sbin/init
    [    3.250061]   with environment:
    [    3.250061]     HOME=/
    [    3.250061]     TERM=linux
    [    3.380310] mmc1: new DDR MMC card at address 0001
    [    3.385925] mmcblk1: mmc1:0001 032GB4 29.1 GiB 
    [    3.392761]  mmcblk1: p1 p2
    [    3.396514] mmcblk1boot0: mmc1:0001 032GB4 8.00 MiB 
    [    3.403106] mmcblk1boot1: mmc1:0001 032GB4 8.00 MiB 
    [    3.409515] mmcblk1rpmb: mmc1:0001 032GB4 4.00 MiB, chardev (242:0)
    [    3.660705] systemd[1]: systemd 250.5+ running in system mode (+PAM -AUDIT -SELINUX -APPARMOR +IMA -SMACK +SECCOMP -GCRYPT -GNUTLS -OPENSSL +ACL +BLKID -CURL -ELFUTILS -FIDO2 -IDN2 -IDN -IPTC +KMOD -LIBCRYPTSETUP +LIBFDISK -PCRE2 -PWQUALITY -P11KIT -QRENCODE -BZIP2 -LZ4 -XZ -ZLIB +ZSTD -BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=hybrid)
    [    3.692962] systemd[1]: Detected architecture arm.
    [    3.725219] systemd[1]: Hostname set to <am57xx-evm>.
    [    3.903442] systemd-sysv-generator[116]: SysV service '/etc/init.d/gdbserverproxy' lacks a native systemd unit file. Automatically generating a unit file for compatibility. Please update package to include a native systemd unit file, in order to make it more safe and robust.
    [    3.928222] systemd-sysv-generator[116]: SysV service '/etc/init.d/thermal-zone-init' lacks a native systemd unit file. Automatically generating a unit file for compatibility. Please update package to include a native systemd unit file, in order to make it more safe and robust.
    [    4.195617] systemd[1]: /lib/systemd/system/bt-enable.service:9: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [    4.260955] systemd[1]: /etc/systemd/system/sys-clock-drift.service:10: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [    4.283325] systemd[1]: /etc/systemd/system/sync-clocks.service:11: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [    4.364013] systemd[1]: Queued start job for default target Graphical Interface.
    [    4.373382] systemd[1]: Created slice Slice /system/getty.
    [    4.415466] systemd[1]: Created slice Slice /system/modprobe.
    [    4.454620] systemd[1]: Created slice Slice /system/serial-getty.
    [    4.494262] systemd[1]: Created slice User and Session Slice.
    [    4.534454] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
    [    4.574005] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
    [    4.614379] systemd[1]: Reached target Path Units.
    [    4.654113] systemd[1]: Reached target Remote File Systems.
    [    4.693908] systemd[1]: Reached target Slice Units.
    [    4.734252] systemd[1]: Reached target Swaps.
    [    4.785888] systemd[1]: Listening on RPCbind Server Activation Socket.
    [    4.823883] systemd[1]: Reached target RPC Port Mapper.
    [    4.874206] systemd[1]: Listening on Process Core Dump Socket.
    [    4.914581] systemd[1]: Listening on initctl Compatibility Named Pipe.
    [    5.001861] systemd[1]: Journal Audit Socket was skipped because of a failed condition check (ConditionSecurity=audit).
    [    5.013336] systemd[1]: Listening on Journal Socket (/dev/log).
    [    5.054809] systemd[1]: Listening on Journal Socket.
    [    5.094329] systemd[1]: Listening on Network Service Netlink Socket.
    [    5.134979] systemd[1]: Listening on udev Control Socket.
    [    5.174133] systemd[1]: Listening on udev Kernel Socket.
    [    5.214843] systemd[1]: Listening on User Database Manager Socket.
    [    5.254241] systemd[1]: Huge Pages File System was skipped because of a failed condition check (ConditionPathExists=/sys/kernel/mm/hugepages).
    [    5.334136] systemd[1]: Mounting POSIX Message Queue File System...
    [    5.376159] systemd[1]: Mounting Kernel Debug File System...
    [    5.416351] systemd[1]: Mounting Kernel Trace File System...
    [    5.465393] systemd[1]: Mounting Temporary Directory /tmp...
    [    5.507904] systemd[1]: Starting Create List of Static Device Nodes...
    [    5.547363] systemd[1]: Starting Load Kernel Module configfs...
    [    5.587097] systemd[1]: Starting Load Kernel Module drm...
    [    5.616821] systemd[1]: Starting Load Kernel Module fuse...
    [    5.658447] systemd[1]: Starting Start psplash boot splash screen...
    [    5.722076] systemd[1]: Starting RPC Bind...
    [    5.754241] systemd[1]: File System Check on Root Device was skipped because of a failed condition check (ConditionPathIsReadWrite=!/).
    [    5.767639] systemd[1]: systemd-journald.service: unit configures an IP firewall, but the local system does not support BPF/cgroup firewalling.
    [    5.780639] systemd[1]: (This warning is only shown for the first unit using IP firewalling.)
    [    5.824493] systemd[1]: Starting Journal Service...
    [    5.887359] systemd[1]: Starting Load Kernel Modules...
    [    5.926177] systemd[1]: Starting Generate network units from Kernel command line...
    [    5.994201] systemd[1]: Starting Remount Root and Kernel File Systems...
    [    6.029083] EXT4-fs (mmcblk0p2): re-mounted. Quota mode: disabled.
    [    6.037841] systemd[1]: Starting Coldplug All udev Devices...
    [    6.090362] systemd[1]: Started RPC Bind.
    [    6.134155] systemd[1]: Started Journal Service.
    [    6.696655] systemd-journald[129]: Received client request to flush runtime journal.
    [    7.585845] omap-sham 4b101000.sham: hw accel on OMAP rev 4.3
    [    7.596313] omap-rproc 58820000.ipu: assigned reserved memory node ipu1-memory@9d000000
    [    7.612152] omap-sham 4b101000.sham: will run requests pump with realtime priority
    [    7.630065] remoteproc remoteproc0: 58820000.ipu is available
    [    7.662322] omap-rproc 55020000.ipu: assigned reserved memory node ipu2-memory@95800000
    [    7.677490] remoteproc remoteproc1: 55020000.ipu is available
    [    7.696990] omap-rproc 40800000.dsp: assigned reserved memory node dsp1-memory@99000000
    [    7.728790] remoteproc remoteproc2: 40800000.dsp is available
    [    7.735626] omap-rproc 41000000.dsp: assigned reserved memory node dsp2-memory@9f000000
    [    7.743774] remoteproc remoteproc3: 41000000.dsp is available
    [    7.984252] omap-sham 42701000.sham: hw accel on OMAP rev 4.3
    [    8.018951] omap-sham 42701000.sham: will run requests pump with realtime priority
    [    8.192871] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: GPIO lookup for consumer id
    [    8.192901] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: using device tree for GPIO lookup
    [    8.192901] of_get_named_gpiod_flags: can't parse 'id-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]'
    [    8.192962] of_get_named_gpiod_flags: can't parse 'id-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]'
    [    8.192993] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: using lookup tables for GPIO lookup
    [    8.192993] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: No GPIO consumer id found
    [    8.192993] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: GPIO lookup for consumer vbus
    [    8.193023] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: using device tree for GPIO lookup
    [    8.193023] of_get_named_gpiod_flags: can't parse 'vbus-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]'
    [    8.193054] of_get_named_gpiod_flags: parsed 'vbus-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]' - status (0)
    [    8.193145] gpio gpiochip5: Persistence not supported for GPIO 21
    [    8.202362] remoteproc remoteproc1: powering up 55020000.ipu
    [    8.208190] remoteproc remoteproc1: Booting fw image dra7-ipu2-fw.xem4, size 3747228
    [    8.217681] omap-iommu 55082000.mmu: 55082000.mmu: version 2.1
    [    8.304443] rproc-virtio rproc-virtio.1.auto: assigned reserved memory node ipu2-memory@95800000
    [    8.318359] virtio_rpmsg_bus virtio0: rpmsg host is online
    [    8.326812] rproc-virtio rproc-virtio.1.auto: registered virtio0 (type 7)
    [    8.339233] remoteproc remoteproc0: powering up 58820000.ipu
    [    8.351409] pwm-backlight backlight: GPIO lookup for consumer enable
    [    8.351409] pwm-backlight backlight: using device tree for GPIO lookup
    [    8.351409] of_get_named_gpiod_flags: can't parse 'enable-gpios' property of node '/backlight[0]'
    [    8.351440] of_get_named_gpiod_flags: can't parse 'enable-gpio' property of node '/backlight[0]'
    [    8.351470] pwm-backlight backlight: using lookup tables for GPIO lookup
    [    8.351470] pwm-backlight backlight: No GPIO consumer enable found
    [    8.351501] pwm-backlight backlight: supply power not found, using dummy regulator
    [    8.367889] remoteproc remoteproc0: Booting fw image dra7-ipu1-fw.xem4, size 4855436
    [    8.376007] remoteproc remoteproc1: remote processor 55020000.ipu is now up
    [    8.383514] omap-iommu 58882000.mmu: no fck found
    [    8.388305] omap-iommu 58882000.mmu: pwrdm_constraint failed to be set, status = -19
    [    8.391815] pwm-backlight backlight: invalid default brightness level: 8, using 7
    [    8.396087] omap-iommu 58882000.mmu: 58882000.mmu: version 2.1
    [    8.398651] rproc-virtio rproc-virtio.2.auto: assigned reserved memory node ipu1-memory@9d000000
    [    8.418975] virtio_rpmsg_bus virtio1: rpmsg host is online
    [    8.426330] rproc-virtio rproc-virtio.2.auto: registered virtio1 (type 7)
    [    8.433166] remoteproc remoteproc0: remote processor 58820000.ipu is now up
    [    8.440826] virtio_rpmsg_bus virtio0: creating channel rpmsg-rpc addr 0x65
    [    8.448608] virtio_rpmsg_bus virtio1: creating channel rpmsg-client-sample addr 0x32
    [    8.456634] virtio_rpmsg_bus virtio1: creating channel rpmsg-client-sample addr 0x33
    [    8.464355] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4571, Function: panel_simple_platform_probe ****************************
    [    8.481567] virtio_rpmsg_bus virtio0: creating channel rpmsg-rpc addr 0x66
    [    8.491333] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 591, Function: panel_simple_probe ****************************
    [    8.506256] virtio_rpmsg_bus virtio1: creating channel rpmsg-omx addr 0x3c
    [    8.513305] virtio_rpmsg_bus virtio1: creating channel rpmsg-rpc addr 0x65
    [    8.526977] videodev: Linux video capture interface: v2.00
    [    8.549713] panel-simple display: supply power not found, using dummy regulator
    [    8.562652] panel-simple display: GPIO lookup for consumer enable
    [    8.562652] panel-simple display: using device tree for GPIO lookup
    [    8.562683] of_get_named_gpiod_flags: parsed 'enable-gpios' property of node '/display[0]' - status (0)
    [    8.562713] gpio gpiochip6: Persistence not supported for GPIO 12
    [    8.562713] panel-simple display: Specify missing connector_type
    [    8.587768] omap_rtc 48838000.rtc: registered as rtc2
    [    8.593322] omap_rtc 48838000.rtc: GPIO lookup for consumer wp
    [    8.593322] omap_rtc 48838000.rtc: using device tree for GPIO lookup
    [    8.593322] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48800000/segment@0/target-module@38000/rtc@0[0]'
    [    8.593353] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48800000/segment@0/target-module@38000/rtc@0[0]'
    [    8.593383] omap_rtc 48838000.rtc: using lookup tables for GPIO lookup
    [    8.593444] omap_rtc 48838000.rtc: No GPIO consumer wp found
    [    8.673095] omap-des 480a5000.des: OMAP DES hw accel rev: 2.2
    [    8.701843] remoteproc remoteproc2: powering up 40800000.dsp
    [    8.714721] remoteproc remoteproc3: powering up 41000000.dsp
    [    8.720428] remoteproc remoteproc3: Booting fw image dra7-dsp2-fw.xe66, size 5536080
    [    8.728729] remoteproc remoteproc2: Booting fw image dra7-dsp1-fw.xe66, size 5535952
    [    8.738494] omap-iommu 40d01000.mmu: 40d01000.mmu: version 3.0
    [    8.744445] omap-iommu 40d02000.mmu: 40d02000.mmu: version 3.0
    [    8.748504] omap-des 480a5000.des: will run requests pump with realtime priority
    [    8.778472] omap-iommu 41501000.mmu: 41501000.mmu: version 3.0
    [    8.784454] omap-iommu 41502000.mmu: 41502000.mmu: version 3.0
    [    8.802917] pinctrl-single 4a003400.pinmux: mux offset out of range: 0xffffe244 (0x468)
    [    8.832214] pinctrl-single 4a003400.pinmux: could not add functions for camera-gpio 4294959684x
    [    8.857574] rproc-virtio rproc-virtio.4.auto: assigned reserved memory node dsp2-memory@9f000000
    [    8.866973] rproc-virtio rproc-virtio.3.auto: assigned reserved memory node dsp1-memory@99000000
    [    8.879241] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3850, Function: ov5640_probe ****************************
    [    8.892944] ov5640 2-003c: GPIO lookup for consumer powerdown
    [    8.892944] ov5640 2-003c: using device tree for GPIO lookup
    [    8.892974] of_get_named_gpiod_flags: parsed 'powerdown-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c[0]' - status (0)
    [    8.893035] gpio gpiochip6: Persistence not supported for GPIO 17
    [    8.893035] ov5640 2-003c: GPIO lookup for consumer reset
    [    8.893035] ov5640 2-003c: using device tree for GPIO lookup
    [    8.893035] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c[0]'
    [    8.893096] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c[0]'
    [    8.893127] ov5640 2-003c: using lookup tables for GPIO lookup
    [    8.893127] ov5640 2-003c: No GPIO consumer reset found
    [    8.893157] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3814, Function: ov5640_get_regulators ****************************
    [    8.907409] ov5640 2-003c: supply DOVDD not found, using dummy regulator
    [    8.929779] ov5640 2-003c: supply AVDD not found, using dummy regulator
    [    8.940155] virtio_rpmsg_bus virtio3: rpmsg host is online
    [    8.946014] rproc-virtio rproc-virtio.3.auto: registered virtio3 (type 7)
    [    8.953521] ov5640 2-003c: supply DVDD not found, using dummy regulator
    [    8.967498] remoteproc remoteproc2: remote processor 40800000.dsp is now up
    [    8.987152] virtio_rpmsg_bus virtio3: creating channel rpmsg-client-sample addr 0x32
    [    9.003540] virtio_rpmsg_bus virtio2: rpmsg host is online
    [    9.009124] virtio_rpmsg_bus virtio2: creating channel rpmsg-client-sample addr 0x32
    [    9.009368] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3442, Function: ov5640_init_controls ****************************
    [    9.020507] virtio_rpmsg_bus virtio3: creating channel rpmsg-client-sample addr 0x33
    [    9.044219] virtio_rpmsg_bus virtio2: creating channel rpmsg-client-sample addr 0x33
    [    9.056854] virtio_rpmsg_bus virtio3: creating channel rpmsg-omx addr 0x3c
    [    9.056854] rproc-virtio rproc-virtio.4.auto: registered virtio2 (type 7)
    [    9.056976] virtio_rpmsg_bus virtio3: creating channel rpmsg-rpc addr 0x65
    [    9.099182] virtio_rpmsg_bus virtio2: creating channel rpmsg-omx addr 0x3c
    [    9.101318] remoteproc remoteproc3: remote processor 41000000.dsp is now up
    [    9.119812] vip 48990000.vip: loading firmware vpdma-1b8.bin
    [    9.137542] virtio_rpmsg_bus virtio2: creating channel rpmsg-rpc addr 0x65
    [    9.148315] vpe 489d0000.vpe: loading firmware vpdma-1b8.bin
    [    9.179260] DSS: OMAP DSS rev 6.1
    [    9.184783] vip 48990000.vip: VPDMA firmware loaded
    [    9.201660] vpe 489d0000.vpe: Device registered as /dev/video0
    [    9.220031] omap_wdt: OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
    [    9.267517] omap-aes 4b500000.aes: OMAP AES hw accel rev: 3.3
    [    9.298095] omap-aes 4b500000.aes: will run requests pump with realtime priority
    [    9.308563] ahci-dwc 4a140000.sata: supply ahci not found, using dummy regulator
    [    9.333282] omapdss_dss 58000000.dss: bound 58001000.dispc (ops dispc_component_ops [omapdrm])
    [    9.349792] ahci-dwc 4a140000.sata: supply phy not found, using dummy regulator
    [    9.422973] dmm 4e000000.dmm: workaround for errata i878 in use
    [    9.427093] omap-aes 4b700000.aes: OMAP AES hw accel rev: 3.3
    [    9.443969] omap-aes 4b700000.aes: will run requests pump with realtime priority
    [    9.453002] ahci-dwc 4a140000.sata: supply target not found, using dummy regulator
    [    9.523925] dmm 4e000000.dmm: initialized all PAT entries
    [    9.540985] ahci-dwc 4a140000.sata: forcing port_map 0x0 -> 0x1
    [    9.600921] ahci-dwc 4a140000.sata: AHCI 0001.0300 32 slots 1 ports 3 Gbps 0x1 impl platform mode
    [    9.610015] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 476, Function: panel_simple_get_orientation ****************************
    [    9.636718] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3827, Function: ov5640_check_chip_id ****************************
    [    9.724548] vin3a: Port A: Using subdev ov5640 2-003c for capture
    [    9.732879] ahci-dwc 4a140000.sata: flags: 64bit ncq sntf pm led clo only pmp pio slum part ccc apst 
    [    9.777160] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [    9.818267] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [    9.881042] scsi host0: ahci-dwc
    [    9.887390] ata1: SATA max UDMA/133 mmio [mem 0x4a140000-0x4a1410ff] port 0x100 irq 171
    [    9.943511] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [    9.957153] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 426, Function: panel_simple_get_modes ****************************
    [   10.083831] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   10.108184] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.200744] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 253, Function: panel_simple_get_non_edid_modes ****************************
    [   10.215332] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.327606] ata1: SATA link down (SStatus 0 SControl 300)
    [   10.333801] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.379852] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 221, Function: panel_simple_get_display_modes ****************************
    [   10.457366] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.541687] [drm] Enabling DMM ywrap scrolling
    [   10.591339] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 388, Function: panel_simple_prepare ****************************
    [   10.591339] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   10.591369] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 364, Function: panel_simple_resume ****************************
    [   10.591369] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 299, Function: panel_simple_wait ****************************
    [   10.632568] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.632568] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.632568] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.632568] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.632598] **** vip: create_stream: V4L2_MBUS_BT656 ****
    [   10.747802] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 409, Function: panel_simple_enable ****************************
    [   10.747833] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   10.814544] Console: switching to colour frame buffer device 128x37
    [   11.126190] omapdrm omapdrm.0: [drm] fb0: omapdrmdrmfb frame buffer device
    [   11.165435] [drm] Initialized omapdrm 1.0.0 20110917 for omapdrm.0 on minor 0
    [   11.307342] remoteproc remoteproc4: 4b234000.pru is available
    [   11.374786] remoteproc remoteproc5: 4b238000.pru is available
    [   11.381347] remoteproc remoteproc6: 4b2b4000.pru is available
    [   11.433197] remoteproc remoteproc7: 4b2b8000.pru is available
    [   13.427124] EXT4-fs (mmcblk1p2): mounted filesystem with ordered data mode. Quota mode: disabled.
    [   14.016998] Bluetooth: Core ver 2.22
    [   14.026000] NET: Registered PF_BLUETOOTH protocol family
    [   14.041473] Bluetooth: HCI device and connection manager initialized
    [   14.057525] Bluetooth: HCI socket layer initialized
    [   14.057556] Bluetooth: L2CAP socket layer initialized
    [   14.057556] Bluetooth: SCO socket layer initialized
    [   14.178833] cfg80211: Loading compiled-in X.509 certificates for regulatory database
    [   14.464935] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
    [   14.472198] cfg80211: Loaded X.509 cert 'wens: 61c038651aabdcf94bd0ac7ff06c7248db18c600'
    [   14.572448] Initializing XFRM netlink socket
    [   14.654663] cpsw-switch 48484000.switch: starting ndev. mode: dual_mac
    [   14.694396] Generic PHY 48485000.mdio:01: attached PHY driver (mii_bus:phy_addr=48485000.mdio:01, irq=POLL)
    [   14.755493] cpsw-switch 48484000.switch: starting ndev. mode: dual_mac
    [   14.800354] Generic PHY 48485000.mdio:00: attached PHY driver (mii_bus:phy_addr=48485000.mdio:00, irq=POLL)
    [   14.855895] cpsw-switch 48484000.switch eth0: Link is Up - 100Mbps/Full - flow control off
    [   14.864257] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
    [   20.036132] systemd-journald[129]: Time jumped backwards, rotating.
    [   21.614501] platform sound0: deferred probe pending
    [   21.618377] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 426, Function: panel_simple_get_modes ****************************
    [   21.673828] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   21.703735] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 253, Function: panel_simple_get_non_edid_modes ****************************
    [   21.743713] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 221, Function: panel_simple_get_display_modes ****************************
    [   33.144042] ldousb: disabling

    Do you want me to put any prints in driver? Why is the same issue coming yet again. I can share the changes be it DTS or any source code.

    I have already shared with you the DTS file in which I have set the audiocodec as the master. Is this the reason for probe not getting called ?
    Please see my DTS and let me know for any issues in it. 

    Please help resolving the issue if not DTS issue !

     

    -Vishal

  • Please check if the following configurations are enabled in the build.

    • AIC3XXX_CORE
    • AIC3XXX_I2C_REGMAP
    • SND_SOC_AIC3262

    If this still doesn't work, please check if the i2c probe is happening for the driver in driver/mfd/ . If not, I think it is issue with the DTS. Thanks, Niranjan

  • Please check if the following configurations are enabled in the build.

    • AIC3XXX_CORE
    • AIC3XXX_I2C_REGMAP
    • SND_SOC_AIC3262

    Yes they are all set to y, y, and m respectively. When they were not set then there were compilation errors. So I set them manually to get the driver compiled.

    If this still doesn't work, please check if the i2c probe is happening for the driver in driver/mfd/ .

    Ok i will put prints in the probe function in  tlv320aic3xxx-i2c.c file and let you know!

    -Vishal

  •   ,

    I put prints as shown in the diff below and compiled and booted. I hope this only is the file you wanted prints to be put inside of.

    diff --git a/drivers/mfd/tlv320aic3xxx-i2c.c b/drivers/mfd/tlv320aic3xxx-i2c.c
    index c84238632..6dde0b042 100644
    --- a/drivers/mfd/tlv320aic3xxx-i2c.c
    +++ b/drivers/mfd/tlv320aic3xxx-i2c.c
    @@ -39,6 +39,7 @@ struct regmap_config aicxxx_i2c_regmap = {
     #ifdef CONFIG_PM
     static int aic3xxx_suspend(struct device *dev)
     {
    +       printk("VM********************* File: %s, Line: %d, Function: %s ****************************\n", __FILE__, __LINE__, __FUNCTION__);
            struct aic3xxx *aic3xxx = dev_get_drvdata(dev);
     
            aic3xxx->suspended = true;
    @@ -48,6 +49,7 @@ static int aic3xxx_suspend(struct device *dev)
     
     static int aic3xxx_resume(struct device *dev)
     {
    +       printk("VM********************* File: %s, Line: %d, Function: %s ****************************\n", __FILE__, __LINE__, __FUNCTION__);
            struct aic3xxx *aic3xxx = dev_get_drvdata(dev);
     
            aic3xxx->suspended = false;
    @@ -59,6 +61,7 @@ static int aic3xxx_resume(struct device *dev)
     static int aic3xxx_i2c_probe(struct i2c_client *i2c,
                                              const struct i2c_device_id *id)
     {
    +       printk("VM********************* File: %s, Line: %d, Function: %s ****************************\n", __FILE__, __LINE__, __FUNCTION__);
            struct aic3xxx *aicxxx;
            const struct regmap_config *regmap_config;
            int ret;
    @@ -99,6 +102,7 @@ static int aic3xxx_i2c_probe(struct i2c_client *i2c,
     
     static void aic3xxx_i2c_remove(struct i2c_client *i2c)
     {
    +       printk("VM********************* File: %s, Line: %d, Function: %s ****************************\n", __FILE__, __LINE__, __FUNCTION__);
            struct aic3xxx *aicxxx = dev_get_drvdata(&i2c->dev);
            aic3xxx_device_exit(aicxxx);
            //return 0;
    

    But in dmesg below these prints are not getting hit (you can check too )

    [    0.000000] Booting Linux on physical CPU 0x0
    [    0.000000] Linux version 6.1.119-00016-g12fce29825f6-dirty (root@cdot-VirtualBox) (arm-oe-linux-gnueabi-gcc (GCC) 11.5.0, GNU ld (GNU Binutils) 2.38.20220708) #81 SMP PREEMPT Mon Sep  8 11:28:04 IST 2025
    [    0.000000] CPU: ARMv7 Processor [412fc0f2] revision 2 (ARMv7), cr=30c5387d
    [    0.000000] CPU: div instructions available: patching division code
    [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
    [    0.000000] OF: fdt: Machine model: TI AM5728 BeagleBoard-X15 rev C
    [    0.000000] Memory policy: Data cache writealloc
    [    0.000000] efi: UEFI not found.
    [    0.000000] Reserved memory: created CMA memory pool at 0x0000000095800000, size 56 MiB
    [    0.000000] OF: reserved mem: initialized node ipu2-memory@95800000, compatible id shared-dma-pool
    [    0.000000] Reserved memory: created CMA memory pool at 0x0000000099000000, size 64 MiB
    [    0.000000] OF: reserved mem: initialized node dsp1-memory@99000000, compatible id shared-dma-pool
    [    0.000000] Reserved memory: created DMA memory pool at 0x000000009d000000, size 32 MiB
    [    0.000000] OF: reserved mem: initialized node ipu1-memory@9d000000, compatible id shared-dma-pool
    [    0.000000] Reserved memory: created CMA memory pool at 0x000000009f000000, size 8 MiB
    [    0.000000] OF: reserved mem: initialized node dsp2-memory@9f000000, compatible id shared-dma-pool
    [    0.000000] cma: Reserved 64 MiB at 0x00000000ab800000
    [    0.000000] OMAP4: Map 0x00000000afd00000 to (ptrval) for dram barrier
    [    0.000000] Hit pending asynchronous external abort (FSR=0x00001211) during first unmask, this is most likely caused by a firmware/bootloader bug.
    [    0.000000] Zone ranges:
    [    0.000000]   DMA      [mem 0x0000000080000000-0x00000000afcfffff]
    [    0.000000]   Normal   empty
    [    0.000000]   HighMem  [mem 0x00000000afd00000-0x000000027fffffff]
    [    0.000000] Movable zone start for each node
    [    0.000000] Early memory node ranges
    [    0.000000]   node   0: [mem 0x0000000080000000-0x00000000956fffff]
    [    0.000000]   node   0: [mem 0x0000000095700000-0x00000000957fffff]
    [    0.000000]   node   0: [mem 0x0000000095800000-0x000000009cffffff]
    [    0.000000]   node   0: [mem 0x000000009d000000-0x000000009effffff]
    [    0.000000]   node   0: [mem 0x000000009f000000-0x00000000afcfffff]
    [    0.000000]   node   0: [mem 0x00000000b0000000-0x00000000feffffff]
    [    0.000000]   node   0: [mem 0x0000000200000000-0x000000027fffffff]
    [    0.000000] Initmem setup node 0 [mem 0x0000000080000000-0x000000027fffffff]
    [    0.000000] On node 0, zone HighMem: 768 pages in unavailable ranges
    [    0.000000] DRA752 ES2.0
    [    0.000000] clockdomain: ipu1_clkdm: powerdomain ipu_pwrdm does not exist
    [    0.000000] clockdomain: ipu_clkdm: powerdomain ipu_pwrdm does not exist
    [    0.000000] percpu: Embedded 16 pages/cpu s34324 r8192 d23020 u65536
    [    0.000000] pcpu-alloc: s34324 r8192 d23020 u65536 alloc=16*4096
    [    0.000000] pcpu-alloc: [0] 0 [0] 1 
    [    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 1042182
    [    0.000000] Kernel command line: console=ttyS2,115200n8 root=PARTUUID=5c496148-02 rw rootfstype=ext4 rootwait
    [    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes, linear)
    [    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes, linear)
    [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
    [    0.000000] software IO TLB: area num 2.
    [    0.000000] software IO TLB: mapped [mem 0x00000000a3800000-0x00000000a7800000] (64MB)
    [    0.000000] Memory: 3758060K/4174848K available (12288K kernel code, 1469K rwdata, 3308K rodata, 2048K init, 308K bss, 220180K reserved, 196608K cma-reserved, 3325952K highmem)
    [    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
    [    0.000000] trace event string verifier disabled
    [    0.000000] rcu: Preemptible hierarchical RCU implementation.
    [    0.000000] rcu: 	RCU event tracing is enabled.
    [    0.000000] rcu: 	RCU restricting CPUs from NR_CPUS=16 to nr_cpu_ids=2.
    [    0.000000] 	Trampoline variant of Tasks RCU enabled.
    [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
    [    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
    [    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
    [    0.000000] GIC: Using split EOI/Deactivate mode
    [    0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
    [    0.000000] OMAP clocksource: 32k_counter at 32768 Hz
    [    0.000000] clocksource: 32k_counter: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 58327039986419 ns
    [    0.000000] sched_clock: 32 bits at 33kHz, resolution 30517ns, wraps every 65535999984741ns
    [    0.001434] TI gptimer clockevent: always-on 32786 Hz at /ocp/interconnect@4ae00000/segment@10000/target-module@8000
    [    0.003173] TI gptimer percpu-dmtimer: 20000000 Hz at /ocp/interconnect@48800000/segment@0/target-module@2c000
    [    0.003356] TI gptimer percpu-dmtimer: 20000000 Hz at /ocp/interconnect@48800000/segment@0/target-module@2e000
    [    0.004272] Console: colour dummy device 80x30
    [    0.004302] Calibrating delay loop... 1993.93 BogoMIPS (lpj=9969664)
    [    0.062072] CPU: Testing write buffer coherency: ok
    [    0.062103] CPU0: Spectre v2: using ICIALLU workaround
    [    0.062103] CPU0: Spectre BHB: enabling loop workaround for all CPUs
    [    0.062103] pid_max: default: 32768 minimum: 301
    [    0.062255] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes, linear)
    [    0.062255] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes, linear)
    [    0.062896] /cpus/cpu@0 missing clock-frequency property
    [    0.062927] /cpus/cpu@1 missing clock-frequency property
    [    0.062927] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
    [    0.063568] cblist_init_generic: Setting adjustable number of callback queues.
    [    0.063568] cblist_init_generic: Setting shift to 1 and lim to 1.
    [    0.063690] Setting up static identity map for 0x80200000 - 0x80200138
    [    0.063781] rcu: Hierarchical SRCU implementation.
    [    0.063781] rcu: 	Max phase no-delay instances is 1000.
    [    0.065979] EFI services will not be available.
    [    0.066528] smp: Bringing up secondary CPUs ...
    [    0.126739] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
    [    0.126770] CPU1: Spectre v2: using ICIALLU workaround
    [    0.126861] smp: Brought up 1 node, 2 CPUs
    [    0.126892] SMP: Total of 2 processors activated (3994.41 BogoMIPS).
    [    0.126892] CPU: All CPU(s) started in HYP mode.
    [    0.126892] CPU: Virtualization extensions available.
    [    0.127319] devtmpfs: initialized
    [    0.150695] VFP support v0.3: implementor 41 architecture 4 part 30 variant f rev 0
    [    0.150878] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
    [    0.150909] futex hash table entries: 512 (order: 3, 32768 bytes, linear)
    [    0.155395] pinctrl core: initialized pinctrl subsystem
    [    0.156066] DMI not present or invalid.
    [    0.156494] NET: Registered PF_NETLINK/PF_ROUTE protocol family
    [    0.158294] DMA: preallocated 256 KiB pool for atomic coherent allocations
    [    0.159301] thermal_sys: Registered thermal governor 'step_wise'
    [    0.159332] cpuidle: using governor menu
    [    0.185577] platform ocp: Fixed dependency cycle(s) with /ocp/interconnect@4a000000/segment@0/target-module@8000/cm_core@0/clock@e00/clock@20
    [    0.185638] platform ocp: Fixed dependency cycle(s) with /ocp/interconnect@4a000000/segment@0/target-module@8000/cm_core@0/clock@700/clock@20
    [    0.189270] platform display: Fixed dependency cycle(s) with /ocp/target-module@58000000/dss@0
    [    0.190765] No ATAGs?
    [    0.190856] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers.
    [    0.190856] hw-breakpoint: maximum watchpoint size is 8 bytes.
    [    0.208618] reg-fixed-voltage fixedregulator-main_12v0: GPIO lookup for consumer (null)
    [    0.208648] reg-fixed-voltage fixedregulator-main_12v0: using device tree for GPIO lookup
    [    0.208648] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-main_12v0[0]'
    [    0.208679] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-main_12v0[0]'
    [    0.208679] reg-fixed-voltage fixedregulator-main_12v0: using lookup tables for GPIO lookup
    [    0.208709] reg-fixed-voltage fixedregulator-main_12v0: No GPIO consumer (null) found
    [    0.208953] reg-fixed-voltage fixedregulator-evm_5v0: GPIO lookup for consumer (null)
    [    0.208953] reg-fixed-voltage fixedregulator-evm_5v0: using device tree for GPIO lookup
    [    0.208953] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-evm_5v0[0]'
    [    0.208984] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-evm_5v0[0]'
    [    0.208984] reg-fixed-voltage fixedregulator-evm_5v0: using lookup tables for GPIO lookup
    [    0.208984] reg-fixed-voltage fixedregulator-evm_5v0: No GPIO consumer (null) found
    [    0.209594] iommu: Default domain type: Translated 
    [    0.209594] iommu: DMA domain TLB invalidation policy: strict mode 
    [    0.210968] SCSI subsystem initialized
    [    0.211120] libata version 3.00 loaded.
    [    0.211303] usbcore: registered new interface driver usbfs
    [    0.211334] usbcore: registered new interface driver hub
    [    0.211364] usbcore: registered new device driver usb
    [    0.211791] mc: Linux media interface: v0.10
    [    0.211822] pps_core: LinuxPPS API ver. 1 registered
    [    0.211822] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
    [    0.211853] PTP clock support registered
    [    0.211975] EDAC MC: Ver: 3.0.0
    [    0.213806] clocksource: Switched to clocksource 32k_counter
    [    0.221801] NET: Registered PF_INET protocol family
    [    0.221984] IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
    [    0.234588] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes, linear)
    [    0.234588] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
    [    0.234619] TCP established hash table entries: 8192 (order: 3, 32768 bytes, linear)
    [    0.234680] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
    [    0.234893] TCP: Hash tables configured (established 8192 bind 8192)
    [    0.234954] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
    [    0.235015] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
    [    0.235137] NET: Registered PF_UNIX/PF_LOCAL protocol family
    [    0.235534] RPC: Registered named UNIX socket transport module.
    [    0.235565] RPC: Registered udp transport module.
    [    0.235565] RPC: Registered tcp transport module.
    [    0.235565] RPC: Registered tcp NFSv4.1 backchannel transport module.
    [    0.235565] PCI: CLS 0 bytes, default 64
    [    0.235961] armv7-pmu pmu: hw perfevents: no interrupt-affinity property, guessing.
    [    0.236114] hw perfevents: enabled with armv7_cortex_a15 PMU driver, 7 counters available
    [    0.236999] Initialise system trusted keyrings
    [    0.237335] workingset: timestamp_bits=30 max_order=20 bucket_order=0
    [    0.243011] squashfs: version 4.0 (2009/01/31) Phillip Lougher
    [    0.243621] NFS: Registering the id_resolver key type
    [    0.243652] Key type id_resolver registered
    [    0.243652] Key type id_legacy registered
    [    0.243743] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
    [    0.243743] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
    [    0.243774] ntfs: driver 2.1.32 [Flags: R/O].
    [    0.244293] Key type asymmetric registered
    [    0.244293] Asymmetric key parser 'x509' registered
    [    0.244415] bounce: pool size: 64 pages
    [    0.244537] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 246)
    [    0.244537] io scheduler mq-deadline registered
    [    0.244537] io scheduler kyber registered
    [    0.247650] omap_prm: probe of 4ae06500.prm failed with error -22
    [    0.294921] Serial: 8250/16550 driver, 5 ports, IRQ sharing enabled
    [    0.296905] STMicroelectronics ASC driver initialized
    [    0.297515] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4913, Function: panel_simple_init ****************************
    [    0.298889] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4918, Function: panel_simple_init ****************************
    [    0.298889] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4921, Function: panel_simple_init ****************************
    [    0.298889] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4924, Function: panel_simple_init ****************************
    [    0.298919] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4929, Function: panel_simple_init ****************************
    [    0.306152] brd: module loaded
    [    0.310882] loop: module loaded
    [    0.314208] mdio_bus fixed-0: GPIO lookup for consumer reset
    [    0.314208] mdio_bus fixed-0: using lookup tables for GPIO lookup
    [    0.314208] mdio_bus fixed-0: No GPIO consumer reset found
    [    0.315429] CAN device driver interface
    [    0.315826] e1000e: Intel(R) PRO/1000 Network Driver
    [    0.315826] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
    [    0.315856] igb: Intel(R) Gigabit Ethernet Network Driver
    [    0.315856] igb: Copyright (c) 2007-2014 Intel Corporation.
    [    0.316711] pegasus: Pegasus/Pegasus II USB Ethernet driver
    [    0.316741] usbcore: registered new interface driver pegasus
    [    0.316802] usbcore: registered new interface driver asix
    [    0.316833] usbcore: registered new interface driver ax88179_178a
    [    0.316864] usbcore: registered new interface driver cdc_ether
    [    0.316894] usbcore: registered new interface driver smsc75xx
    [    0.316925] usbcore: registered new interface driver smsc95xx
    [    0.316955] usbcore: registered new interface driver net1080
    [    0.316986] usbcore: registered new interface driver cdc_subset
    [    0.317016] usbcore: registered new interface driver zaurus
    [    0.317047] usbcore: registered new interface driver cdc_ncm
    [    0.317749] usbcore: registered new interface driver usb-storage
    [    0.318634] i2c_dev: i2c /dev entries driver
    [    0.321075] sdhci: Secure Digital Host Controller Interface driver
    [    0.321075] sdhci: Copyright(c) Pierre Ossman
    [    0.321258] Synopsys Designware Multimedia Card Interface Driver
    [    0.321472] sdhci-pltfm: SDHCI platform and OF driver helper
    [    0.322082] ledtrig-cpu: registered to indicate activity on CPUs
    [    0.322387] usbcore: registered new interface driver usbhid
    [    0.322387] usbhid: USB HID core driver
    [    0.325012] NET: Registered PF_INET6 protocol family
    [    0.325897] Segment Routing with IPv6
    [    0.325927] In-situ OAM (IOAM) with IPv6
    [    0.325988] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
    [    0.326477] NET: Registered PF_PACKET protocol family
    [    0.326477] can: controller area network core
    [    0.326538] NET: Registered PF_CAN protocol family
    [    0.326538] can: raw protocol
    [    0.326538] can: broadcast manager protocol
    [    0.326568] can: netlink gateway - max_hops=1
    [    0.326721] Key type dns_resolver registered
    [    0.326782] ThumbEE CPU extension supported.
    [    0.326782] Registering SWP/SWPB emulation handler
    [    0.327178] omap_voltage_late_init: Voltage driver support not added
    [    0.327209] Power Management for TI OMAP4+ devices.
    [    0.327972] Loading compiled-in X.509 certificates
    [    0.361206] platform 4a000000.interconnect: Fixed dependency cycle(s) with /ocp/interconnect@4a000000/segment@0/target-module@8000/cm_core@0/clock@d00/clock@20
    [    0.367156] pinctrl-single 4a003400.pinmux: 282 pins, size 1128
    [    0.389556] omap-dma-engine 4a056000.dma-controller: OMAP DMA engine driver (LinkedList1/2/3 supported)
    [    0.405883] gpio gpiochip0: (gpio-0-31): not an immutable chip, please consider fixing it!
    [    0.406127] gpio gpiochip0: (gpio-0-31): added GPIO chardev (254:0)
    [    0.406219] gpio gpiochip0: registered GPIOs 0 to 31 on gpio-0-31
    [    0.406280] OMAP GPIO hardware version 0.1
    [    0.408538] ti-sysc: probe of 4ae18000.target-module failed with error -16
    [    0.415649] printk: console [ttyS2] disabled
    [    0.415649] omap8250 48020000.serial: GPIO lookup for consumer rs485-term
    [    0.415649] omap8250 48020000.serial: using device tree for GPIO lookup
    [    0.415679] of_get_named_gpiod_flags: can't parse 'rs485-term-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@20000/serial@0[0]'
    [    0.415710] of_get_named_gpiod_flags: can't parse 'rs485-term-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@20000/serial@0[0]'
    [    0.415740] omap8250 48020000.serial: using lookup tables for GPIO lookup
    [    0.415771] omap8250 48020000.serial: No GPIO consumer rs485-term found
    [    0.415771] 48020000.serial: ttyS2 at MMIO 0x48020000 (irq = 100, base_baud = 3000000) is a 8250
    [    1.728851] printk: console [ttyS2] enabled
    [    1.740844] gpio gpiochip1: (gpio-32-63): not an immutable chip, please consider fixing it!
    [    1.749633] gpio gpiochip1: (gpio-32-63): added GPIO chardev (254:1)
    [    1.749694] gpio gpiochip1: registered GPIOs 32 to 63 on gpio-32-63
    [    1.750976] gpio gpiochip2: (gpio-64-95): not an immutable chip, please consider fixing it!
    [    1.759521] gpio gpiochip2: (gpio-64-95): added GPIO chardev (254:2)
    [    1.759613] gpio gpiochip2: registered GPIOs 64 to 95 on gpio-64-95
    [    1.760864] gpio gpiochip3: (gpio-96-127): not an immutable chip, please consider fixing it!
    [    1.769470] gpio gpiochip3: (gpio-96-127): added GPIO chardev (254:3)
    [    1.769561] gpio gpiochip3: registered GPIOs 96 to 127 on gpio-96-127
    [    1.770721] gpio gpiochip4: (gpio-128-159): not an immutable chip, please consider fixing it!
    [    1.779449] gpio gpiochip4: (gpio-128-159): added GPIO chardev (254:4)
    [    1.779510] gpio gpiochip4: registered GPIOs 128 to 159 on gpio-128-159
    [    1.780700] gpio gpiochip5: (gpio-160-191): not an immutable chip, please consider fixing it!
    [    1.789398] gpio gpiochip5: (gpio-160-191): added GPIO chardev (254:5)
    [    1.789459] gpio gpiochip5: registered GPIOs 160 to 191 on gpio-160-191
    [    1.790924] gpio gpiochip6: (gpio-192-223): not an immutable chip, please consider fixing it!
    [    1.799621] gpio gpiochip6: (gpio-192-223): added GPIO chardev (254:6)
    [    1.799713] gpio gpiochip6: registered GPIOs 192 to 223 on gpio-192-223
    [    1.800994] gpio gpiochip7: (gpio-224-255): not an immutable chip, please consider fixing it!
    [    1.809722] gpio gpiochip7: (gpio-224-255): added GPIO chardev (254:7)
    [    1.809783] gpio gpiochip7: registered GPIOs 224 to 255 on gpio-224-255
    [    1.811645] i2c i2c-2: GPIO lookup for consumer scl
    [    1.811676] i2c i2c-2: using device tree for GPIO lookup
    [    1.811676] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811706] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811767] i2c i2c-2: using lookup tables for GPIO lookup
    [    1.811767] i2c i2c-2: No GPIO consumer scl found
    [    1.811767] i2c i2c-2: GPIO lookup for consumer sda
    [    1.811798] i2c i2c-2: using device tree for GPIO lookup
    [    1.811798] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811828] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0[0]'
    [    1.811859] i2c i2c-2: using lookup tables for GPIO lookup
    [    1.811889] i2c i2c-2: No GPIO consumer sda found
    [    1.812347] i2c 2-003c: Fixed dependency cycle(s) with /ocp/interconnect@48800000/target-module@190000/vip@0
    [    1.822509] omap_i2c 48060000.i2c: bus 2 rev0.12 at 400 kHz
    [    1.831695] omap8250 4806a000.serial: GPIO lookup for consumer rs485-term
    [    1.831726] omap8250 4806a000.serial: using device tree for GPIO lookup
    [    1.831726] of_get_named_gpiod_flags: can't parse 'rs485-term-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@6a000/serial@0[0]'
    [    1.831756] of_get_named_gpiod_flags: can't parse 'rs485-term-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@6a000/serial@0[0]'
    [    1.831817] omap8250 4806a000.serial: using lookup tables for GPIO lookup
    [    1.831817] omap8250 4806a000.serial: No GPIO consumer rs485-term found
    [    1.831848] 4806a000.serial: ttyS0 at MMIO 0x4806a000 (irq = 114, base_baud = 3000000) is a 8250
    [    1.844055] i2c i2c-0: GPIO lookup for consumer scl
    [    1.844055] i2c i2c-0: using device tree for GPIO lookup
    [    1.844055] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.844116] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.844146] i2c i2c-0: using lookup tables for GPIO lookup
    [    1.844146] i2c i2c-0: No GPIO consumer scl found
    [    1.844177] i2c i2c-0: GPIO lookup for consumer sda
    [    1.844177] i2c i2c-0: using device tree for GPIO lookup
    [    1.844177] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.844207] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0[0]'
    [    1.844268] i2c i2c-0: using lookup tables for GPIO lookup
    [    1.844268] i2c i2c-0: No GPIO consumer sda found
    [    1.844696] palmas 0-0058: Irq flag is 0x00000008
    [    1.876525] palmas 0-0058: Muxing GPIO 2b, PWM 0, LED 0
    [    1.908142] gpiochip_find_base: found new base at 504
    [    1.908325] gpio gpiochip8: (48070000.i2c:tps659038@58:tps659038_gpio): added GPIO chardev (254:8)
    [    1.908386] gpio gpiochip8: registered GPIOs 504 to 511 on 48070000.i2c:tps659038@58:tps659038_gpio
    [    1.909362] at24 0-0050: supply vcc not found, using dummy regulator
    [    1.916076] at24 0-0050: GPIO lookup for consumer wp
    [    1.916107] at24 0-0050: using device tree for GPIO lookup
    [    1.916107] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/eeprom@50[0]'
    [    1.916168] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/eeprom@50[0]'
    [    1.916198] at24 0-0050: using lookup tables for GPIO lookup
    [    1.916198] at24 0-0050: No GPIO consumer wp found
    [    1.916320] at24 0-0050: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
    [    1.923309] omap_i2c 48070000.i2c: bus 0 rev0.12 at 400 kHz
    [    1.930847] i2c i2c-1: GPIO lookup for consumer scl
    [    1.930847] i2c i2c-1: using device tree for GPIO lookup
    [    1.930847] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.930908] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.930938] i2c i2c-1: using lookup tables for GPIO lookup
    [    1.930938] i2c i2c-1: No GPIO consumer scl found
    [    1.930969] i2c i2c-1: GPIO lookup for consumer sda
    [    1.930969] i2c i2c-1: using device tree for GPIO lookup
    [    1.930969] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.931030] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@72000/i2c@0[0]'
    [    1.931060] i2c i2c-1: using lookup tables for GPIO lookup
    [    1.931060] i2c i2c-1: No GPIO consumer sda found
    [    1.931579] omap_i2c 48072000.i2c: bus 1 rev0.12 at 400 kHz
    [    1.939361] i2c i2c-3: GPIO lookup for consumer scl
    [    1.939392] i2c i2c-3: using device tree for GPIO lookup
    [    1.939392] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939422] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939453] i2c i2c-3: using lookup tables for GPIO lookup
    [    1.939483] i2c i2c-3: No GPIO consumer scl found
    [    1.939483] i2c i2c-3: GPIO lookup for consumer sda
    [    1.939483] i2c i2c-3: using device tree for GPIO lookup
    [    1.939514] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939544] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7a000/i2c@0[0]'
    [    1.939575] i2c i2c-3: using lookup tables for GPIO lookup
    [    1.939575] i2c i2c-3: No GPIO consumer sda found
    [    1.939819] omap_i2c 4807a000.i2c: bus 3 rev0.12 at 400 kHz
    [    1.946960] i2c i2c-4: GPIO lookup for consumer scl
    [    1.946960] i2c i2c-4: using device tree for GPIO lookup
    [    1.946990] of_get_named_gpiod_flags: can't parse 'scl-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.947021] of_get_named_gpiod_flags: can't parse 'scl-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.947052] i2c i2c-4: using lookup tables for GPIO lookup
    [    1.947052] i2c i2c-4: No GPIO consumer scl found
    [    1.947082] i2c i2c-4: GPIO lookup for consumer sda
    [    1.947082] i2c i2c-4: using device tree for GPIO lookup
    [    1.947113] of_get_named_gpiod_flags: can't parse 'sda-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.947143] of_get_named_gpiod_flags: can't parse 'sda-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0[0]'
    [    1.947174] i2c i2c-4: using lookup tables for GPIO lookup
    [    1.947174] i2c i2c-4: No GPIO consumer sda found
    [    1.947448] omap_i2c 4807c000.i2c: bus 4 rev0.12 at 400 kHz
    [    1.953430] edt_ft5x06 4-0038: supply vcc not found, using dummy regulator
    [    1.960540] edt_ft5x06 4-0038: supply iovcc not found, using dummy regulator
    [    1.964752] omap_rng 48090000.rng: Random Number Generator ver. 20
    [    1.967773] random: crng init done
    [    1.977294] edt_ft5x06 4-0038: GPIO lookup for consumer reset
    [    1.977294] edt_ft5x06 4-0038: using device tree for GPIO lookup
    [    1.977294] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.977355] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.977386] edt_ft5x06 4-0038: using lookup tables for GPIO lookup
    [    1.977416] edt_ft5x06 4-0038: No GPIO consumer reset found
    [    1.977416] edt_ft5x06 4-0038: GPIO lookup for consumer wake
    [    1.977416] edt_ft5x06 4-0038: using device tree for GPIO lookup
    [    1.977447] of_get_named_gpiod_flags: can't parse 'wake-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.977508] of_get_named_gpiod_flags: can't parse 'wake-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@7c000/i2c@0/edt-ft5x06@38[0]'
    [    1.977569] edt_ft5x06 4-0038: using lookup tables for GPIO lookup
    [    1.977569] edt_ft5x06 4-0038: No GPIO consumer wake found
    [    1.999450] mdio_bus 48485000.mdio: GPIO lookup for consumer reset
    [    1.999481] mdio_bus 48485000.mdio: using device tree for GPIO lookup
    [    1.999481] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000[0]'
    [    1.999542] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000[0]'
    [    1.999572] mdio_bus 48485000.mdio: using lookup tables for GPIO lookup
    [    1.999603] mdio_bus 48485000.mdio: No GPIO consumer reset found
    [    2.005981] input: 4-0038 generic ft5x06 (8d) as /devices/platform/ocp/48000000.interconnect/48000000.interconnect:segment@0/4807c000.target-module/4807c000.i2c/i2c-4/4-0038/input/input0
    [    2.063842] davinci_mdio 48485000.mdio: davinci mdio revision 1.6, bus freq 1000000
    [    2.072357] mdio_bus 48485000.mdio:00: GPIO lookup for consumer reset
    [    2.072357] mdio_bus 48485000.mdio:00: using device tree for GPIO lookup
    [    2.072387] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@0[0]'
    [    2.072448] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@0[0]'
    [    2.072479] mdio_bus 48485000.mdio:00: using lookup tables for GPIO lookup
    [    2.072479] mdio_bus 48485000.mdio:00: No GPIO consumer reset found
    [    2.073364] mdio_bus 48485000.mdio:01: GPIO lookup for consumer reset
    [    2.073394] mdio_bus 48485000.mdio:01: using device tree for GPIO lookup
    [    2.073394] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@1[0]'
    [    2.073455] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48400000/segment@0/target-module@84000/switch@0/mdio@1000/ethernet-phy@1[0]'
    [    2.073516] mdio_bus 48485000.mdio:01: using lookup tables for GPIO lookup
    [    2.073516] mdio_bus 48485000.mdio:01: No GPIO consumer reset found
    [    2.073669] davinci_mdio 48485000.mdio: phy[0]: device 48485000.mdio:00, driver unknown
    [    2.081756] davinci_mdio 48485000.mdio: phy[1]: device 48485000.mdio:01, driver unknown
    [    2.090393] cpsw-switch 48484000.switch: initialized cpsw ale version 1.4
    [    2.097259] cpsw-switch 48484000.switch: ALE Table size 1024
    [    2.102996] cpsw-switch 48484000.switch: cpts: overflow check period 500 (jiffies)
    [    2.110626] cpsw-switch 48484000.switch: CPTS: ref_clk_freq:266000000 calc_mult:4036623398 calc_shift:30 error:-1 nsec/sec
    [    2.121765] cpsw-switch 48484000.switch: Detected MACID = d0:03:eb:6c:3f:16
    [    2.128814] cpsw-switch 48484000.switch: Detected MACID = d0:03:eb:6c:3f:17
    [    2.137603] cpsw-switch 48484000.switch: initialized (regs 0x0000000048484000, pool size 256) hw_ver:0019010F 1.15 (0)
    [    2.159942] ti-sysc: probe of 4882c000.target-module failed with error -16
    [    2.167633] ti-sysc: probe of 4882e000.target-module failed with error -16
    [    2.178527] omap-mailbox 48840000.mailbox: omap mailbox rev 0x400
    [    2.185760] omap-mailbox 48842000.mailbox: omap mailbox rev 0x400
    [    2.200347] i2c 2-003c: Fixed dependency cycle(s) with /ocp/interconnect@48800000/target-module@190000/vip@0
    [    2.210327] platform 48990000.vip: Fixed dependency cycle(s) with /ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c
    [    2.226684] dra7-pcie 51000000.pcie: GPIO lookup for consumer (null)
    [    2.226684] dra7-pcie 51000000.pcie: using device tree for GPIO lookup
    [    2.226715] of_get_named_gpiod_flags: parsed 'gpios' property of node '/ocp/target-module@51000000/pcie@51000000[0]' - status (0)
    [    2.226776] gpio gpiochip3: Persistence not supported for GPIO 8
    [    2.227020] dra7-pcie 51000000.pcie: host bridge /ocp/target-module@51000000/pcie@51000000 ranges:
    [    2.236083] dra7-pcie 51000000.pcie:       IO 0x0020003000..0x0020012fff -> 0x0000000000
    [    2.244293] dra7-pcie 51000000.pcie:      MEM 0x0020013000..0x002fffffff -> 0x0020013000
    [    2.252624] dra7-pcie 51000000.pcie: iATU unroll: disabled
    [    2.258178] dra7-pcie 51000000.pcie: iATU regions: 16 ob, 4 ib, align 4K, limit 4G
    [    2.365875] dra7-pcie 51000000.pcie: PCIe Gen.2 x1 link up
    [    2.371520] dra7-pcie 51000000.pcie: PCI host bridge to bus 0000:00
    [    2.377838] pci_bus 0000:00: root bus resource [bus 00-ff]
    [    2.383361] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
    [    2.389587] pci_bus 0000:00: root bus resource [mem 0x20013000-0x2fffffff]
    [    2.396545] pci 0000:00:00.0: [104c:8888] type 01 class 0x060400
    [    2.402587] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
    [    2.408905] pci 0000:00:00.0: reg 0x14: [mem 0x00000000-0x0000ffff]
    [    2.415283] pci 0000:00:00.0: supports D1
    [    2.419311] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
    [    2.432250] PCI: bus0: Fast back to back transfers disabled
    [    2.438049] pci 0000:01:00.0: [8086:2526] type 00 class 0x028000
    [    2.444183] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00003fff 64bit]
    [    2.451354] pci 0000:01:00.0: PME# supported from D0 D3hot D3cold
    [    2.643981] PCI: bus1: Fast back to back transfers disabled
    [    2.649597] pci 0000:00:00.0: BAR 0: assigned [mem 0x20100000-0x201fffff]
    [    2.656463] pci 0000:00:00.0: BAR 8: assigned [mem 0x20200000-0x202fffff]
    [    2.663269] pci 0000:00:00.0: BAR 1: assigned [mem 0x20020000-0x2002ffff]
    [    2.670135] pci 0000:01:00.0: BAR 0: assigned [mem 0x20200000-0x20203fff 64bit]
    [    2.677520] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
    [    2.682769] pci 0000:00:00.0:   bridge window [mem 0x20200000-0x202fffff]
    [    2.689971] pcieport 0000:00:00.0: PME: Signaling with IRQ 138
    [    2.701965] edma 43300000.dma: memcpy is disabled
    [    2.710144] edma 43300000.dma: TI EDMA DMA engine driver
    [    2.721893] omap-iommu 40d01000.mmu: 40d01000.mmu registered
    [    2.729705] omap-iommu 40d02000.mmu: 40d02000.mmu registered
    [    2.736358] platform 40800000.dsp: Adding to iommu group 0
    [    2.743377] platform 58820000.ipu: Adding to iommu group 1
    [    2.749053] omap-iommu 58882000.mmu: 58882000.mmu registered
    [    2.757019] platform 55020000.ipu: Adding to iommu group 2
    [    2.762573] omap-iommu 55082000.mmu: 55082000.mmu registered
    [    2.774780] platform display: Fixed dependency cycle(s) with /ocp/target-module@58000000/dss@0
    [    2.783538] platform 58000000.dss: Fixed dependency cycle(s) with /display
    [    2.799407] omap-iommu 41501000.mmu: 41501000.mmu registered
    [    2.806701] omap-iommu 41502000.mmu: 41502000.mmu registered
    [    2.813537] platform 41000000.dsp: Adding to iommu group 3
    [    2.821594] ti-sysc 4ae06000.target-module: Failed to create device link (0x180) with ocp
    [    2.831329] gpio-clk clk_ov5640: GPIO lookup for consumer enable
    [    2.831329] gpio-clk clk_ov5640: using device tree for GPIO lookup
    [    2.831390] of_get_named_gpiod_flags: parsed 'enable-gpios' property of node '/clk_ov5640[0]' - status (0)
    [    2.831420] gpio gpiochip6: Persistence not supported for GPIO 18
    [    2.835510] reg-fixed-voltage fixedregulator-vdd_3v3: GPIO lookup for consumer (null)
    [    2.835510] reg-fixed-voltage fixedregulator-vdd_3v3: using device tree for GPIO lookup
    [    2.835540] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-vdd_3v3[0]'
    [    2.835540] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-vdd_3v3[0]'
    [    2.835571] reg-fixed-voltage fixedregulator-vdd_3v3: using lookup tables for GPIO lookup
    [    2.835571] reg-fixed-voltage fixedregulator-vdd_3v3: No GPIO consumer (null) found
    [    2.836029] reg-fixed-voltage fixedregulator-aic_dvdd: GPIO lookup for consumer (null)
    [    2.836029] reg-fixed-voltage fixedregulator-aic_dvdd: using device tree for GPIO lookup
    [    2.836029] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-aic_dvdd[0]'
    [    2.836059] of_get_named_gpiod_flags: can't parse 'gpio' property of node '/fixedregulator-aic_dvdd[0]'
    [    2.836059] reg-fixed-voltage fixedregulator-aic_dvdd: using lookup tables for GPIO lookup
    [    2.836059] reg-fixed-voltage fixedregulator-aic_dvdd: No GPIO consumer (null) found
    [    2.836334] reg-fixed-voltage fixedregulator-vtt: GPIO lookup for consumer (null)
    [    2.836334] reg-fixed-voltage fixedregulator-vtt: using device tree for GPIO lookup
    [    2.836334] of_get_named_gpiod_flags: can't parse 'gpios' property of node '/fixedregulator-vtt[0]'
    [    2.836364] of_get_named_gpiod_flags: parsed 'gpio' property of node '/fixedregulator-vtt[0]' - status (0)
    [    2.836395] gpio gpiochip1: Persistence not supported for GPIO 11
    [    2.865814] rtc-ds1307 2-006f: registered as rtc0
    [    2.870849] rtc-ds1307 2-006f: setting system clock to 2025-09-08T05:59:21 UTC (1757311161)
    [    2.879302] rtc-ds1307 2-006f: GPIO lookup for consumer wp
    [    2.879302] rtc-ds1307 2-006f: using device tree for GPIO lookup
    [    2.879302] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/rtc@6f[0]'
    [    2.879364] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/rtc@6f[0]'
    [    2.879394] rtc-ds1307 2-006f: using lookup tables for GPIO lookup
    [    2.879394] rtc-ds1307 2-006f: No GPIO consumer wp found
    [    2.882354] palmas-rtc 48070000.i2c:tps659038@58:tps659038_rtc: registered as rtc1
    [    2.891784] sdhci-omap 4809c000.mmc: GPIO lookup for consumer cd
    [    2.891784] sdhci-omap 4809c000.mmc: using device tree for GPIO lookup
    [    2.891815] of_get_named_gpiod_flags: parsed 'cd-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@9c000/mmc@0[0]' - status (0)
    [    2.891876] gpio gpiochip7: Persistence not supported for GPIO 27
    [    2.891876] omap_gpio 4805d000.gpio: Could not set line 27 debounce to 200000 microseconds (-22)
    [    2.892089] sdhci-omap 480b4000.mmc: GPIO lookup for consumer wp
    [    2.900756] sdhci-omap 4809c000.mmc: Got CD GPIO
    [    2.901275] sdhci-omap 480b4000.mmc: using device tree for GPIO lookup
    [    2.905426] sdhci-omap 4809c000.mmc: GPIO lookup for consumer wp
    [    2.905426] sdhci-omap 4809c000.mmc: using device tree for GPIO lookup
    [    2.905456] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@9c000/mmc@0[0]'
    [    2.905487] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@9c000/mmc@0[0]'
    [    2.905517] sdhci-omap 4809c000.mmc: using lookup tables for GPIO lookup
    [    2.905548] sdhci-omap 4809c000.mmc: No GPIO consumer wp found
    [    2.905822] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@b4000/mmc@0[0]'
    [    2.905883] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@b4000/mmc@0[0]'
    [    2.905944] sdhci-omap 480b4000.mmc: using lookup tables for GPIO lookup
    [    2.905975] sdhci-omap 480b4000.mmc: No GPIO consumer wp found
    [    2.906127] sdhci-omap 480b4000.mmc: supply pbias not found, using dummy regulator
    [    2.906646] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 1147, Function: gpio_keys_init ****************************
    [    2.926788] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 870, Function: gpio_keys_probe ****************************
    [    2.939727] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 788, Function: gpio_keys_get_devtree_pdata ****************************
    [    2.953765] sdhci-omap 4809c000.mmc: no pinctrl state for ddr_3_3v mode
    [    2.953765] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 523, Function: gpio_keys_setup_key ****************************
    [    2.973724] of_get_named_gpiod_flags: parsed 'gpios' property of node '/gpio-keys/button-user1[0]' - status (0)
    [    2.973754] gpio gpiochip0: Persistence not supported for GPIO 14
    [    2.973876] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 523, Function: gpio_keys_setup_key ****************************
    [    2.987182] of_get_named_gpiod_flags: parsed 'gpios' property of node '/gpio-keys/button-user2[0]' - status (0)
    [    2.987182] gpio gpiochip3: Persistence not supported for GPIO 6
    [    2.987274] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 523, Function: gpio_keys_setup_key ****************************
    [    2.999145] mmc1: SDHCI controller on 480b4000.mmc [480b4000.mmc] using ADMA
    [    3.000549] of_get_named_gpiod_flags: parsed 'gpios' property of node '/gpio-keys/button-user3[0]' - status (0)
    [    3.007629] gpio gpiochip6: Persistence not supported for GPIO 1
    [    3.007812] input: gpio-keys as /devices/platform/gpio-keys/input/input1
    [    3.014556] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 751, Function: gpio_keys_open ****************************
    [    3.020599] mmc0: SDHCI controller on 4809c000.mmc [4809c000.mmc] using ADMA
    [    3.027404] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 737, Function: gpio_keys_report_state ****************************
    [    3.027404] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 376, Function: gpio_keys_gpio_report_event ****************************
    [    3.027435] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 376, Function: gpio_keys_gpio_report_event ****************************
    [    3.068878] mmc0: new high speed SDHC card at address 5048
    [    3.076049] VM********************* File: drivers/input/keyboard/gpio_keys.c, Line: 376, Function: gpio_keys_gpio_report_event ****************************
    [    3.081909] mmcblk0: mmc0:5048 SD32G 29.7 GiB 
    [    3.096862] clk: Disabling unused clocks
    [    3.106353]  mmcblk0: p1 p2
    [    3.138031] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Quota mode: disabled.
    [    3.147003] VFS: Mounted root (ext4 filesystem) on device 179:2.
    [    3.160522] devtmpfs: mounted
    [    3.164825] Freeing unused kernel image (initmem) memory: 2048K
    [    3.170379] mmc1: new DDR MMC card at address 0001
    [    3.175750] Run /sbin/init as init process
    [    3.179931]   with arguments:
    [    3.179931]     /sbin/init
    [    3.179931]   with environment:
    [    3.179931]     HOME=/
    [    3.179931]     TERM=linux
    [    3.180145] mmcblk1: mmc1:0001 032GB4 29.1 GiB 
    [    3.186523]  mmcblk1: p1 p2
    [    3.189758] mmcblk1boot0: mmc1:0001 032GB4 8.00 MiB 
    [    3.195892] mmcblk1boot1: mmc1:0001 032GB4 8.00 MiB 
    [    3.201721] mmcblk1rpmb: mmc1:0001 032GB4 4.00 MiB, chardev (242:0)
    [    3.583984] systemd[1]: systemd 250.5+ running in system mode (+PAM -AUDIT -SELINUX -APPARMOR +IMA -SMACK +SECCOMP -GCRYPT -GNUTLS -OPENSSL +ACL +BLKID -CURL -ELFUTILS -FIDO2 -IDN2 -IDN -IPTC +KMOD -LIBCRYPTSETUP +LIBFDISK -PCRE2 -PWQUALITY -P11KIT -QRENCODE -BZIP2 -LZ4 -XZ -ZLIB +ZSTD -BPF_FRAMEWORK -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=hybrid)
    [    3.615997] systemd[1]: Detected architecture arm.
    [    3.655181] systemd[1]: Hostname set to <am57xx-evm>.
    [    3.792144] systemd-sysv-generator[103]: SysV service '/etc/init.d/gdbserverproxy' lacks a native systemd unit file. Automatically generating a unit file for compatibility. Please update package to include a native systemd unit file, in order to make it more safe and robust.
    [    3.817413] systemd-sysv-generator[103]: SysV service '/etc/init.d/thermal-zone-init' lacks a native systemd unit file. Automatically generating a unit file for compatibility. Please update package to include a native systemd unit file, in order to make it more safe and robust.
    [    4.085083] systemd[1]: /lib/systemd/system/bt-enable.service:9: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [    4.150268] systemd[1]: /etc/systemd/system/sys-clock-drift.service:10: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [    4.172637] systemd[1]: /etc/systemd/system/sync-clocks.service:11: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether.
    [    4.253082] systemd[1]: Queued start job for default target Graphical Interface.
    [    4.262512] systemd[1]: Created slice Slice /system/getty.
    [    4.305328] systemd[1]: Created slice Slice /system/modprobe.
    [    4.344726] systemd[1]: Created slice Slice /system/serial-getty.
    [    4.384704] systemd[1]: Created slice User and Session Slice.
    [    4.424133] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
    [    4.464324] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
    [    4.504394] systemd[1]: Reached target Path Units.
    [    4.534027] systemd[1]: Reached target Remote File Systems.
    [    4.574035] systemd[1]: Reached target Slice Units.
    [    4.604034] systemd[1]: Reached target Swaps.
    [    4.646270] systemd[1]: Listening on RPCbind Server Activation Socket.
    [    4.684051] systemd[1]: Reached target RPC Port Mapper.
    [    4.737670] systemd[1]: Listening on Process Core Dump Socket.
    [    4.774322] systemd[1]: Listening on initctl Compatibility Named Pipe.
    [    4.861755] systemd[1]: Journal Audit Socket was skipped because of a failed condition check (ConditionSecurity=audit).
    [    4.873199] systemd[1]: Listening on Journal Socket (/dev/log).
    [    4.915008] systemd[1]: Listening on Journal Socket.
    [    4.964477] systemd[1]: Listening on Network Service Netlink Socket.
    [    5.004486] systemd[1]: Listening on udev Control Socket.
    [    5.044860] systemd[1]: Listening on udev Kernel Socket.
    [    5.084289] systemd[1]: Listening on User Database Manager Socket.
    [    5.124450] systemd[1]: Huge Pages File System was skipped because of a failed condition check (ConditionPathExists=/sys/kernel/mm/hugepages).
    [    5.204284] systemd[1]: Mounting POSIX Message Queue File System...
    [    5.246307] systemd[1]: Mounting Kernel Debug File System...
    [    5.334228] systemd[1]: Mounting Kernel Trace File System...
    [    5.388275] systemd[1]: Mounting Temporary Directory /tmp...
    [    5.427978] systemd[1]: Starting Create List of Static Device Nodes...
    [    5.534454] systemd[1]: Starting Load Kernel Module configfs...
    [    5.577270] systemd[1]: Starting Load Kernel Module drm...
    [    5.617401] systemd[1]: Starting Load Kernel Module fuse...
    [    5.658538] systemd[1]: Starting Start psplash boot splash screen...
    [    5.709228] systemd[1]: Starting RPC Bind...
    [    5.744354] systemd[1]: File System Check on Root Device was skipped because of a failed condition check (ConditionPathIsReadWrite=!/).
    [    5.757751] systemd[1]: systemd-journald.service: unit configures an IP firewall, but the local system does not support BPF/cgroup firewalling.
    [    5.770843] systemd[1]: (This warning is only shown for the first unit using IP firewalling.)
    [    5.834472] systemd[1]: Starting Journal Service...
    [    5.878265] systemd[1]: Starting Load Kernel Modules...
    [    5.916015] systemd[1]: Starting Generate network units from Kernel command line...
    [    5.956176] systemd[1]: Starting Remount Root and Kernel File Systems...
    [    5.988342] EXT4-fs (mmcblk0p2): re-mounted. Quota mode: disabled.
    [    5.997131] systemd[1]: Starting Coldplug All udev Devices...
    [    6.040374] systemd[1]: Started RPC Bind.
    [    6.084320] systemd[1]: Started Journal Service.
    [    6.668060] systemd-journald[116]: Received client request to flush runtime journal.
    [    7.496643] omap-rproc 58820000.ipu: assigned reserved memory node ipu1-memory@9d000000
    [    7.526916] omap-sham 4b101000.sham: hw accel on OMAP rev 4.3
    [    7.544250] remoteproc remoteproc0: 58820000.ipu is available
    [    7.545654] omap-sham 4b101000.sham: will run requests pump with realtime priority
    [    7.567871] omap-rproc 55020000.ipu: assigned reserved memory node ipu2-memory@95800000
    [    7.656646] remoteproc remoteproc1: 55020000.ipu is available
    [    7.711334] omap-rproc 40800000.dsp: assigned reserved memory node dsp1-memory@99000000
    [    7.755004] omap-sham 42701000.sham: hw accel on OMAP rev 4.3
    [    7.763885] omap-sham 42701000.sham: will run requests pump with realtime priority
    [    7.791656] remoteproc remoteproc2: 40800000.dsp is available
    [    7.818481] omap-rproc 41000000.dsp: assigned reserved memory node dsp2-memory@9f000000
    [    7.827056] remoteproc remoteproc3: 41000000.dsp is available
    [    7.872009] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: GPIO lookup for consumer id
    [    7.872009] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: using device tree for GPIO lookup
    [    7.872039] of_get_named_gpiod_flags: can't parse 'id-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]'
    [    7.872070] of_get_named_gpiod_flags: can't parse 'id-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]'
    [    7.872161] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: using lookup tables for GPIO lookup
    [    7.872161] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: No GPIO consumer id found
    [    7.872192] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: GPIO lookup for consumer vbus
    [    7.872192] palmas-usb 48070000.i2c:tps659038@58:tps659038_usb: using device tree for GPIO lookup
    [    7.872192] of_get_named_gpiod_flags: can't parse 'vbus-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]'
    [    7.872283] of_get_named_gpiod_flags: parsed 'vbus-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@70000/i2c@0/tps659038@58/tps659038_usb[0]' - status (0)
    [    7.872406] gpio gpiochip5: Persistence not supported for GPIO 21
    [    7.955627] videodev: Linux video capture interface: v2.00
    [    7.957916] remoteproc remoteproc0: powering up 58820000.ipu
    [    7.972167] remoteproc remoteproc0: Booting fw image dra7-ipu1-fw.xem4, size 4855436
    [    7.985168] omap-iommu 58882000.mmu: no fck found
    [    7.989898] omap-iommu 58882000.mmu: pwrdm_constraint failed to be set, status = -19
    [    7.997741] omap-iommu 58882000.mmu: 58882000.mmu: version 2.1
    [    8.017852] rproc-virtio rproc-virtio.1.auto: assigned reserved memory node ipu1-memory@9d000000
    [    8.038879] virtio_rpmsg_bus virtio0: rpmsg host is online
    [    8.044799] virtio_rpmsg_bus virtio0: creating channel rpmsg-client-sample addr 0x32
    [    8.065948] rproc-virtio rproc-virtio.1.auto: registered virtio0 (type 7)
    [    8.082092] virtio_rpmsg_bus virtio0: creating channel rpmsg-client-sample addr 0x33
    [    8.090270] remoteproc remoteproc1: powering up 55020000.ipu
    [    8.097381] remoteproc remoteproc0: remote processor 58820000.ipu is now up
    [    8.100616] remoteproc remoteproc1: Booting fw image dra7-ipu2-fw.xem4, size 3747228
    [    8.104522] virtio_rpmsg_bus virtio0: creating channel rpmsg-omx addr 0x3c
    [    8.128448] virtio_rpmsg_bus virtio0: creating channel rpmsg-rpc addr 0x65
    [    8.166870] omap-iommu 55082000.mmu: 55082000.mmu: version 2.1
    [    8.310211] pwm-backlight backlight: GPIO lookup for consumer enable
    [    8.310241] pwm-backlight backlight: using device tree for GPIO lookup
    [    8.310241] of_get_named_gpiod_flags: can't parse 'enable-gpios' property of node '/backlight[0]'
    [    8.310272] of_get_named_gpiod_flags: can't parse 'enable-gpio' property of node '/backlight[0]'
    [    8.310272] pwm-backlight backlight: using lookup tables for GPIO lookup
    [    8.310302] pwm-backlight backlight: No GPIO consumer enable found
    [    8.310333] pwm-backlight backlight: supply power not found, using dummy regulator
    [    8.327819] pwm-backlight backlight: invalid default brightness level: 8, using 7
    [    8.337554] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 4571, Function: panel_simple_platform_probe ****************************
    [    8.355712] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 591, Function: panel_simple_probe ****************************
    [    8.372711] panel-simple display: supply power not found, using dummy regulator
    [    8.380249] panel-simple display: GPIO lookup for consumer enable
    [    8.380279] panel-simple display: using device tree for GPIO lookup
    [    8.380279] of_get_named_gpiod_flags: parsed 'enable-gpios' property of node '/display[0]' - status (0)
    [    8.380310] gpio gpiochip6: Persistence not supported for GPIO 12
    [    8.380310] panel-simple display: Specify missing connector_type
    [    8.428863] omap_rtc 48838000.rtc: registered as rtc2
    [    8.439300] omap_rtc 48838000.rtc: GPIO lookup for consumer wp
    [    8.439331] omap_rtc 48838000.rtc: using device tree for GPIO lookup
    [    8.439331] of_get_named_gpiod_flags: can't parse 'wp-gpios' property of node '/ocp/interconnect@48800000/segment@0/target-module@38000/rtc@0[0]'
    [    8.439392] of_get_named_gpiod_flags: can't parse 'wp-gpio' property of node '/ocp/interconnect@48800000/segment@0/target-module@38000/rtc@0[0]'
    [    8.439422] omap_rtc 48838000.rtc: using lookup tables for GPIO lookup
    [    8.439422] omap_rtc 48838000.rtc: No GPIO consumer wp found
    [    8.454284] rproc-virtio rproc-virtio.2.auto: assigned reserved memory node ipu2-memory@95800000
    [    8.477233] virtio_rpmsg_bus virtio1: rpmsg host is online
    [    8.480651] virtio_rpmsg_bus virtio1: creating channel rpmsg-rpc addr 0x65
    [    8.489837] rproc-virtio rproc-virtio.2.auto: registered virtio1 (type 7)
    [    8.501647] omap-des 480a5000.des: OMAP DES hw accel rev: 2.2
    [    8.508514] virtio_rpmsg_bus virtio1: creating channel rpmsg-rpc addr 0x66
    [    8.519287] omap-des 480a5000.des: will run requests pump with realtime priority
    [    8.521514] remoteproc remoteproc1: remote processor 55020000.ipu is now up
    [    8.600433] pinctrl-single 4a003400.pinmux: mux offset out of range: 0xffffe244 (0x468)
    [    8.626220] remoteproc remoteproc2: powering up 40800000.dsp
    [    8.635009] remoteproc remoteproc2: Booting fw image dra7-dsp1-fw.xe66, size 5535952
    [    8.647613] remoteproc remoteproc3: powering up 41000000.dsp
    [    8.655151] remoteproc remoteproc3: Booting fw image dra7-dsp2-fw.xe66, size 5536080
    [    8.663238] pinctrl-single 4a003400.pinmux: could not add functions for camera-gpio 4294959684x
    [    8.665527] omap-iommu 40d01000.mmu: 40d01000.mmu: version 3.0
    [    8.677947] omap-iommu 40d02000.mmu: 40d02000.mmu: version 3.0
    [    8.686309] ahci-dwc 4a140000.sata: supply ahci not found, using dummy regulator
    [    8.695495] omap_wdt: OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
    [    8.710388] omap-iommu 41501000.mmu: 41501000.mmu: version 3.0
    [    8.716339] omap-iommu 41502000.mmu: 41502000.mmu: version 3.0
    [    8.749877] ahci-dwc 4a140000.sata: supply phy not found, using dummy regulator
    [    8.773803] rproc-virtio rproc-virtio.3.auto: assigned reserved memory node dsp2-memory@9f000000
    [    8.795806] rproc-virtio rproc-virtio.4.auto: assigned reserved memory node dsp1-memory@99000000
    [    8.809265] virtio_rpmsg_bus virtio2: rpmsg host is online
    [    8.815673] virtio_rpmsg_bus virtio3: rpmsg host is online
    [    8.831268] rproc-virtio rproc-virtio.3.auto: registered virtio2 (type 7)
    [    8.838287] rproc-virtio rproc-virtio.4.auto: registered virtio3 (type 7)
    [    8.846099] remoteproc remoteproc3: remote processor 41000000.dsp is now up
    [    8.850769] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3850, Function: ov5640_probe ****************************
    [    8.863861] remoteproc remoteproc2: remote processor 40800000.dsp is now up
    [    8.874786] virtio_rpmsg_bus virtio2: creating channel rpmsg-client-sample addr 0x32
    [    8.877044] vpe 489d0000.vpe: loading firmware vpdma-1b8.bin
    [    8.882659] virtio_rpmsg_bus virtio2: creating channel rpmsg-client-sample addr 0x33
    [    8.888671] vip 48990000.vip: loading firmware vpdma-1b8.bin
    [    8.899414] ahci-dwc 4a140000.sata: supply target not found, using dummy regulator
    [    8.923889] vip 48990000.vip: VPDMA firmware loaded
    [    8.929077] vpe 489d0000.vpe: Device registered as /dev/video0
    [    8.950286] ahci-dwc 4a140000.sata: forcing port_map 0x0 -> 0x1
    [    8.964324] omap-aes 4b500000.aes: OMAP AES hw accel rev: 3.3
    [    8.994354] ahci-dwc 4a140000.sata: AHCI 0001.0300 32 slots 1 ports 3 Gbps 0x1 impl platform mode
    [    8.995910] omap-aes 4b500000.aes: will run requests pump with realtime priority
    [    9.017120] virtio_rpmsg_bus virtio2: creating channel rpmsg-omx addr 0x3c
    [    9.024383] ov5640 2-003c: GPIO lookup for consumer powerdown
    [    9.024383] ov5640 2-003c: using device tree for GPIO lookup
    [    9.024414] of_get_named_gpiod_flags: parsed 'powerdown-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c[0]' - status (0)
    [    9.024475] gpio gpiochip6: Persistence not supported for GPIO 17
    [    9.024475] ov5640 2-003c: GPIO lookup for consumer reset
    [    9.024505] ov5640 2-003c: using device tree for GPIO lookup
    [    9.024505] of_get_named_gpiod_flags: can't parse 'reset-gpios' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c[0]'
    [    9.024566] of_get_named_gpiod_flags: can't parse 'reset-gpio' property of node '/ocp/interconnect@48000000/segment@0/target-module@60000/i2c@0/ov5640@3c[0]'
    [    9.024627] ov5640 2-003c: using lookup tables for GPIO lookup
    [    9.024627] ov5640 2-003c: No GPIO consumer reset found
    [    9.024627] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3814, Function: ov5640_get_regulators ****************************
    [    9.037567] ahci-dwc 4a140000.sata: flags: 64bit ncq sntf pm led clo only pmp pio slum part ccc apst 
    [    9.047515] virtio_rpmsg_bus virtio3: creating channel rpmsg-client-sample addr 0x32
    [    9.061004] ov5640 2-003c: supply DOVDD not found, using dummy regulator
    [    9.068572] virtio_rpmsg_bus virtio3: creating channel rpmsg-client-sample addr 0x33
    [    9.079010] ov5640 2-003c: supply AVDD not found, using dummy regulator
    [    9.079742] omap-aes 4b700000.aes: OMAP AES hw accel rev: 3.3
    [    9.085845] virtio_rpmsg_bus virtio3: creating channel rpmsg-omx addr 0x3c
    [    9.101562] scsi host0: ahci-dwc
    [    9.110137] virtio_rpmsg_bus virtio2: creating channel rpmsg-rpc addr 0x65
    [    9.117218] ov5640 2-003c: supply DVDD not found, using dummy regulator
    [    9.117858] ata1: SATA max UDMA/133 mmio [mem 0x4a140000-0x4a1410ff] port 0x100 irq 167
    [    9.132568] virtio_rpmsg_bus virtio3: creating channel rpmsg-rpc addr 0x65
    [    9.139801] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3442, Function: ov5640_init_controls ****************************
    [    9.153045] omap-aes 4b700000.aes: will run requests pump with realtime priority
    [    9.192749] DSS: OMAP DSS rev 6.1
    [    9.203979] omapdss_dss 58000000.dss: bound 58001000.dispc (ops dispc_component_ops [omapdrm])
    [    9.307281] dmm 4e000000.dmm: workaround for errata i878 in use
    [    9.370178] dmm 4e000000.dmm: initialized all PAT entries
    [    9.455352] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 476, Function: panel_simple_get_orientation ****************************
    [    9.497802] ata1: SATA link down (SStatus 0 SControl 300)
    [    9.562591] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3827, Function: ov5640_check_chip_id ****************************
    [    9.628082] vin3a: Port A: Using subdev ov5640 2-003c for capture
    [    9.638854] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [    9.687255] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [    9.787780] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 426, Function: panel_simple_get_modes ****************************
    [    9.814849] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [    9.868682] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [    9.889434] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [    9.922424] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 253, Function: panel_simple_get_non_edid_modes ****************************
    [    9.941680] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [    9.974029] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [    9.983978] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 221, Function: panel_simple_get_display_modes ****************************
    [   10.003082] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.037536] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.066467] [drm] Enabling DMM ywrap scrolling
    [   10.088012] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 388, Function: panel_simple_prepare ****************************
    [   10.088043] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   10.088073] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 364, Function: panel_simple_resume ****************************
    [   10.088073] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 299, Function: panel_simple_wait ****************************
    [   10.093994] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.094024] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.094024] VM********************* File: drivers/media/i2c/ov5640.c, Line: 3689, Function: ov5640_enum_mbus_code ****************************
    [   10.094024] **** vip: create_stream: V4L2_MBUS_BT656 ****
    [   10.205230] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 409, Function: panel_simple_enable ****************************
    [   10.205230] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   10.288635] Console: switching to colour frame buffer device 128x37
    [   10.459442] omapdrm omapdrm.0: [drm] fb0: omapdrmdrmfb frame buffer device
    [   10.494781] [drm] Initialized omapdrm 1.0.0 20110917 for omapdrm.0 on minor 0
    [   11.314208] remoteproc remoteproc4: 4b234000.pru is available
    [   11.329101] remoteproc remoteproc5: 4b238000.pru is available
    [   11.391143] remoteproc remoteproc6: 4b2b4000.pru is available
    [   11.428680] remoteproc remoteproc7: 4b2b8000.pru is available
    [   13.155761] EXT4-fs (mmcblk1p2): mounted filesystem with ordered data mode. Quota mode: disabled.
    [   13.769378] Bluetooth: Core ver 2.22
    [   13.783874] NET: Registered PF_BLUETOOTH protocol family
    [   13.789245] Bluetooth: HCI device and connection manager initialized
    [   13.803863] Bluetooth: HCI socket layer initialized
    [   13.808807] Bluetooth: L2CAP socket layer initialized
    [   13.823883] Bluetooth: SCO socket layer initialized
    [   13.996002] cfg80211: Loading compiled-in X.509 certificates for regulatory database
    [   14.165374] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
    [   14.174621] cfg80211: Loaded X.509 cert 'wens: 61c038651aabdcf94bd0ac7ff06c7248db18c600'
    [   14.312286] cpsw-switch 48484000.switch: starting ndev. mode: dual_mac
    [   14.375213] Generic PHY 48485000.mdio:01: attached PHY driver (mii_bus:phy_addr=48485000.mdio:01, irq=POLL)
    [   14.424072] Initializing XFRM netlink socket
    [   14.434417] cpsw-switch 48484000.switch: starting ndev. mode: dual_mac
    [   14.506744] Generic PHY 48485000.mdio:00: attached PHY driver (mii_bus:phy_addr=48485000.mdio:00, irq=POLL)
    [   14.548583] cpsw-switch 48484000.switch eth0: Link is Up - 100Mbps/Full - flow control off
    [   14.556945] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
    [   18.638610] systemd-journald[116]: Time jumped backwards, rotating.
    [   21.213867] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 426, Function: panel_simple_get_modes ****************************
    [   21.244079] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 181, Function: to_panel_simple ****************************
    [   21.273864] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 253, Function: panel_simple_get_non_edid_modes ****************************
    [   21.313842] VM********************* File: drivers/gpu/drm/panel/panel-simple.c, Line: 221, Function: panel_simple_get_display_modes ****************************
    [   21.624694] platform sound0: deferred probe pending
    [   33.134063] ldousb: disabling

    Is some compatible string  meant for i2c probing missing in the DTS?

    Or, is it some clock issue. May be clocks are not properly set in DTS for i2c probing.

    Problem is not getting identified actually! 

    -Vishal