| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786 |
- /*
- * ark1668ed_audio_codec.c -- ARK SoC audio driver
- */
- #include <linux/clk.h>
- #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/spi/spi.h>
- #include <linux/platform_device.h>
- #include <linux/slab.h>
- #include <linux/of_gpio.h>
- #include <sound/core.h>
- #include <sound/pcm.h>
- #include <sound/pcm_params.h>
- #include <sound/tlv.h>
- #include <sound/soc.h>
- #include <sound/soc-dapm.h>
- #include <sound/initval.h>
- #include <linux/proc_fs.h>
- #include <linux/gpio.h>
- #include <linux/interrupt.h>
- #include <linux/irq.h>
- #include <linux/regmap.h>
- #include "ark1668ed_i2s.h"
- //#define ARK_CODEC_DEBUG
- #define ARKADAC_RATES \
- (SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
- SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | \
- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_8000)
- #define ARKADAC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
- static struct snd_soc_component *ark_codec_component;
- struct regval_list {
- unsigned int addr;
- unsigned int data;
- };
- static struct regval_list ark_codec_init_regs[] = {
- //{0x00, 0x00}, /**/
- //{0x00, 0x03}, /*Reset ADC/DAC*/
- //{0x15, 0x00},
- {0x47, 0x00},
- {0xF3, 0xc0},
- //{0x15, 0x0b}, /*mic-bias:active*/
- {0x16, 0x0f}, /*LADC/RADC LPGA/RPGA:active*/
- {0x18, 0xf3}, /*LDAC/RDAC,LHeadset/RHeadset,Lline/Rline:active*/
- {0x19, 0x04}, /*Differential-line:active*/
- {0x1d, 0x00}, /*Recording/Input PGA volume control 0:un-mute 1:mute*/
- {0x1f, 0x00}, /*Playback/Headset/Line volume control 0:un-mute 1:mute*/
- {0x21, 0x00}, /*Line volume control 0:un-mute 1:mute*/
- {0x24, 0xbfbf}, /*Recording digital master volume control(left/right channel)*/
- {0x26, 0x1212}, /*Input PGA volume control(left/right channel)*/
- {0x34, 0xe7e7}, /*Digital playback master volume control(left/right channel)*/
- {0x38, 0x0d0d}, /*Headset analog volume control(left/right channel)*/
- {0x47, 0x0101}, /*PGA input selection((single ended)-ainl1p/ainr1n)*/
- {0x59, 0x0101}, /*Playback path channel analog mixer input selection*/
- {0x5d, 0x0101}, /*Playback path channel analog mixer input selection*/
- {0x7b, 0x00}, /*Record digital mixer selection*/
- {0x7c, 0x00}, /*Playback digital mixer selection*/
- {0x7d, 0x00}, /*ASRC1 digital mixer selection*/
- {0x80, 0x0000}, /**/
- {0x88, 0x3f3f}, /**/
- {0x82, 0x3f3f}, /**/
- {0x8a, 0x0000}, /**/
- {0x01, 0x05}, /*Set external clock clk_ext(mclk)=12288kHz*/
- {0xDC, 0x00},
- {0xFB, 0x09},
- {0x13, 0x00},
- {0xA2, 0x00},
- {0x03, 0x01},
- {0x04, 0x40}, /*master_mode_valid:play_lrclk_div 0x7d(fs=48k clk_ext(mclk)=12MHz) 0x40(12.288M)*/
- {0x05, 0x04}, /*master_mode_valid:play_sclk_div 0x2(fs=48k clk_ext(mclk)=12MHz) 0x4(12.288M)*/
- {0x06, 0x40}, /*master_mode_valid:rec_lrclk_div 0x7d(fs=48k clk_ext(mclk)=12MHz) 0x40(12.288M)*/
- {0x07, 0x04}, /*master_mode_valid:rec_sclk_div 0x2(fs=48k clk_ext(mclk)=12MHz) 0x4(12.288M)*/
- //{0x00, 0x00}, /**/
- //{0x00, 0x03}, /*Reset ADC/DAC*/
- //{0x15, 0x01},
- {0x03, 0x31}, /*set i2s data_format,mode,data_len,bit[2:0]:0x1:i2s bit[3]:0:slave/1:master bit[5:4]:0x11:16bit*/
- };
- struct ark_codec_priv {
- struct regmap *regmap;
- struct snd_soc_component *component;
- struct clk *mclk;
- struct i2c_client *i2c;
- void __iomem *sys_base;
- int master;
- unsigned int sample_rate;
- unsigned int volume_left;
- unsigned int volume_right;
- unsigned int mic_volume_left;
- unsigned int mic_volume_right;
- bool mute_left;
- bool mute_right;
- //bool mute;
- };
- #ifdef ARK_CODEC_DEBUG
- #define arkdbgprt printk
- #else
- #define arkdbgprt(format, arg...) do {} while (0)
- #endif
- static const char *const ark_input_sel[] = {
- "Mic"
- };
- //static SOC_ENUM_SINGLE_DECL(ark_input_enum, ADC_CODEC_REG_CTRL1, 0, ark_input_sel);
- static unsigned int arkcodec_register_size(struct device *dev,
- unsigned int reg)
- {
- switch (reg) {
- case CODEC_REG_RECVOL:
- case CODEC_REG_PGA1VOL:
- case CODEC_REG_LMVOL:
- case CODEC_REG_HS1VOL:
- case CODEC_REG_PGA1SEL:
- case CODEC_REG_LDR1SEL:
- case CODEC_REG_LDR2SEL:
- case CODEC_REG_RECPBVOL:
- case CODEC_REG_RECI2S1VOL:
- case CODEC_REG_I2S1PBVOL:
- case CODEC_REG_I2S1I2S1VOL:
- return 2;
- default:
- return 1;
- }
- dev_err(dev, "Unsupported register address: %d\n", reg);
- return 0;
- }
- static int codec_reg_write(struct i2c_client *client, unsigned int reg, unsigned int value)
- {
- unsigned int data_len;
- int ret;
- uint8_t buf[3];
- unsigned int pos = 0;
- data_len = arkcodec_register_size(&client->dev, reg);
- buf[pos++] = reg & 0xFF;
- if (data_len == 1) {
- buf[pos++] = value & 0xFF;
- } else {
- buf[pos++] = (value >> 8) & 0xFF;
- buf[pos++] = value & 0xFF;
- }
- ret = i2c_master_send(client, buf, pos);
- if (ret < 0) {
- dev_err(&client->dev, "I2C write error: %d\n", ret);
- return ret;
- } else if (ret != pos) {
- dev_err(&client->dev, "I2C write: short transfer (%d)\n", ret);
- return -EIO;
- } else
- return 0;
- }
- static int codec_reg_read(struct i2c_client *client, unsigned int reg, unsigned int *value)
- {
- int ret;
- //unsigned int i;
- unsigned int data_len, reg_len;
- uint8_t addr_buf[2] = {0}, data_buf[2] = {0};
- struct i2c_msg msgs[2];
- data_len = arkcodec_register_size(&client->dev, reg);
- if (data_len == 0)
- return -EINVAL;
- addr_buf[0] = reg & 0xFF;
- reg_len = 1;
- msgs[0].addr = client->addr;
- msgs[0].len = reg_len;
- msgs[0].buf = addr_buf;
- msgs[0].flags = 0;
- msgs[1].addr = client->addr;
- msgs[1].len = data_len;
- msgs[1].buf = data_buf;
- msgs[1].flags = I2C_M_RD;
- ret = i2c_transfer(client->adapter, msgs, 2);
- if (ret < 0)
- return ret;
- else if (ret != 2)
- return -EIO;
- if (data_len == 2) {
- *value = (data_buf[0] << 8) | data_buf[1];
- } else {
- *value = data_buf[0];
- }
- return 0;
- }
- static int ark_dac_l_playback_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- ucontrol->value.integer.value[0] = arkcodec->volume_left;
- return 0;
- }
- static int ark_dac_l_playback_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- unsigned int val = ucontrol->value.integer.value[0];
- int change = 0;
- if (arkcodec->volume_left != val) {
- arkcodec->volume_left = val;
- //printk("[set:val = 0x%04x\n",(arkcodec->volume_left << 8) | arkcodec->volume_right);
- codec_reg_write(arkcodec->i2c, CODEC_REG_LMVOL, (arkcodec->volume_left << 8) | arkcodec->volume_right);
- change = 1;
- }
- return change;
- }
- static int ark_dac_r_playback_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- ucontrol->value.integer.value[0] = arkcodec->volume_right;
- return 0;
- }
- static int ark_dac_r_playback_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- unsigned int val = ucontrol->value.integer.value[0];
- int change = 0;
- if (arkcodec->volume_right != val) {
- arkcodec->volume_right = val;
- //printk("[set:val = 0x%04x\n",(arkcodec->volume_left << 8) | arkcodec->volume_right);
- codec_reg_write(arkcodec->i2c, CODEC_REG_LMVOL, (arkcodec->volume_left << 8) | arkcodec->volume_right);
- change = 1;
- }
- return change;
- }
- static int ark_adc_l_capture_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- ucontrol->value.integer.value[0] = arkcodec->mic_volume_left;
- return 0;
- }
- static int ark_adc_l_capture_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- unsigned int val = ucontrol->value.integer.value[0];
- int change = 0;
- if (arkcodec->mic_volume_left != val) {
- arkcodec->mic_volume_left = val;
- //printk("[set:val = 0x%04x\n",(arkcodec->mic_volume_left << 8) | arkcodec->mic_volume_right);
- codec_reg_write(arkcodec->i2c, CODEC_REG_RECVOL, (arkcodec->mic_volume_left << 8) | arkcodec->mic_volume_right);
- change = 1;
- }
- return change;
- }
- static int ark_adc_r_capture_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- ucontrol->value.integer.value[0] = arkcodec->mic_volume_right;
- return 0;
- }
- static int ark_adc_r_capture_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- unsigned int val = ucontrol->value.integer.value[0];
- int change = 0;
- if (arkcodec->mic_volume_right != val) {
- arkcodec->mic_volume_right = val;
- //printk("[set:val = 0x%04x\n",(arkcodec->mic_volume_left << 8) | arkcodec->mic_volume_right);
- codec_reg_write(arkcodec->i2c, CODEC_REG_RECVOL, (arkcodec->mic_volume_left << 8) | arkcodec->mic_volume_right);
- change = 1;
- }
- return change;
- }
- static int ark_dac_mute_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- ucontrol->value.integer.value[0] = arkcodec->mute_left;
- ucontrol->value.integer.value[1] = arkcodec->mute_right;
- return 0;
- }
- static int ark_dac_mute_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
- {
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ark_codec_priv *arkcodec = snd_soc_component_get_drvdata(component);
- unsigned int left = ucontrol->value.integer.value[0];
- unsigned int right = ucontrol->value.integer.value[1];
- unsigned int mute_val = 0;
- int change = 0;
- if (arkcodec->mute_left != left || arkcodec->mute_right != right) {
- arkcodec->mute_left = left;
- arkcodec->mute_right = right;
- if (left)
- mute_val |= MUTE_BIT_LEFT;
- if (right)
- mute_val |= MUTE_BIT_RIGHT;
- //printk("[set:mute_val = %d\n",mute_val);
- regmap_update_bits(arkcodec->regmap, CODEC_REG_PLAYBACK_MUTE, 0x3, mute_val);
- change = 1;
- }
- return change;
- }
- static const DECLARE_TLV_DB_SCALE(ark_dac_vol_tlv, -11550, 50, 0);/*\D2\F4\C1\BF\B7\B6Χ:[-115.5dB-12dB],\B2\BD\B3\A4 :0.5dB*/
- static const DECLARE_TLV_DB_SCALE(ark_mic_vol_tlv, -9550, 50, 0);/*\D2\F4\C1\BF\B7\B6Χ:[-95.5dB-12dB], \B2\BD\B3\A4 :0.5dB*/
- static const struct snd_kcontrol_new ark_codec_controls[] = {
- SOC_SINGLE_EXT("DAC Left Playback Volume", 0, 0, 255, 0,
- ark_dac_l_playback_volume_get, ark_dac_l_playback_volume_put),
- SOC_SINGLE_EXT("DAC Right Playback Volume", 0, 0, 255, 0,
- ark_dac_r_playback_volume_get, ark_dac_r_playback_volume_put),
- SOC_SINGLE_EXT("ADC Left Capture Volume", 0, 0, 255, 0,
- ark_adc_l_capture_volume_get, ark_adc_l_capture_volume_put),
- SOC_SINGLE_EXT("ADC Right Capture Volume", 0, 0, 255, 0,
- ark_adc_r_capture_volume_get, ark_adc_r_capture_volume_put),
- SOC_DOUBLE_EXT("Playback Switch", CODEC_REG_PLAYBACK_MUTE, 0, 1, 1, 1,
- ark_dac_mute_get, ark_dac_mute_put),
- };
- static const struct snd_soc_dapm_widget dwc_audio_dapm_widgets[] = {
- SND_SOC_DAPM_DAC("DAC", "Playback", CODEC_REG_DAC_RESET_CTRL, 0, 0),
- SND_SOC_DAPM_ADC("ADC", "Capture", CODEC_REG_ADC_RESET_CTRL, 1, 0),
- };
- static const struct snd_soc_dapm_route dwc_audio_dapm_routes[] = {
- {"DAC", NULL, "Playback"},
- {"ADC", NULL, "Capture"},
- };
- static int ark_codec_init_reg(struct snd_soc_component *component)
- {
- arkdbgprt("[ARK_CODEC] %s(%d)\n", __func__, __LINE__);
- struct ark_codec_priv *priv = snd_soc_component_get_drvdata(component);
- unsigned int val;
- int i;
- /*reset codec*/
- regmap_write(priv->regmap, CODEC_REG_ADC_DAC_RESET, 0);
- mdelay(2);
- regmap_write(priv->regmap, CODEC_REG_ADC_DAC_RESET, 0x3);
- /*init-regs*/
- for (i = 0; i < ARRAY_SIZE(ark_codec_init_regs); i++) {
- codec_reg_write(priv->i2c, ark_codec_init_regs[i].addr, ark_codec_init_regs[i].data);
- //printk("[write:reg=0x%02x,val=0x%04x]\n",ark_codec_init_regs[i].addr,ark_codec_init_regs[i].data);
- }
- #if 0
- for (i = 0; i < ARRAY_SIZE(ark_codec_init_regs); i++) {
- codec_reg_read(priv->i2c, ark_codec_init_regs[i].addr, &val);
- printk("[read:reg=0x%02x,val=0x%04x]\n", ark_codec_init_regs[i], val);
- }
- #endif
- /*Mic_Bias power-down*/
- regmap_write(priv->regmap, CODEC_REG_POWER_DOWN, 0);
- mdelay(2);
- regmap_write(priv->regmap, CODEC_REG_POWER_DOWN, 0xb);
- codec_reg_read(priv->i2c, CODEC_REG_LMVOL, &val);
- priv->volume_left = (val >> 8) & 0xFF;
- priv->volume_right = val & 0xFF;
- codec_reg_read(priv->i2c, CODEC_REG_RECVOL, &val);
- priv->mic_volume_left = (val >> 8) & 0xFF;
- priv->mic_volume_right = val & 0xFF;
- priv->mute_left = false;
- priv->mute_right = false;
- return 0;
- }
- //static unsigned int ark_codec_read(struct snd_soc_component *component,
- // unsigned int reg)
- //{
- // int val;
- // val = snd_soc_component_read(component,reg);
- // return val;
- //}
- //static int ark_codec_write(struct snd_soc_component *component,
- // unsigned int reg, unsigned int value)
- //{
- // int ret;
- // ret = snd_soc_component_write(component, reg, value);
- // return ret;
- //}
- static int ark_codec_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
- {
- return 0;
- }
- static void ark_codec_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
- {
- }
- static int ark_codec_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
- {
- struct ark_codec_priv *priv = snd_soc_component_get_drvdata(dai->component);
- //int regval = 0;
- unsigned int clk_div, bclk_div;
- arkdbgprt("[ARK_CODEC] %s(%d)\n", __func__, __LINE__);
- priv->sample_rate = params_rate(params);
- switch (priv->sample_rate) {
- case 8000:
- case 16000:
- case 32000:
- clk_div = 3;
- break;
- case 44100:
- case 88200:
- clk_div = 2;
- break;
- case 48000:
- case 96000:
- clk_div = 1;
- break;
- default:
- return -EINVAL;
- }
- switch (params_width(params)) {
- case 16:
- bclk_div = 0;
- break;
- case 24:
- bclk_div = 1;
- break;
- case 32:
- bclk_div = 2;
- break;
- default:
- return -EINVAL;
- }
- /*set rate*/
- // switch (params_rate(params)) {
- // case 48000:
- // regval = CTRL1_SAMPLE_RATE_48K;
- // break;
- // default:
- // dev_err(dai->dev, "Unsupported sample rate: %d\n", params_rate(params));
- // return -EINVAL;
- // }
- //regmap_update_bits(priv->regmap, ADC_CODEC_REG_CTRL1, 0xF0, regval);
- return 0;
- }
- static int ark_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai,
- int clk_id, unsigned int freq, int dir)
- {
- arkdbgprt("[ARK_CODEC] %s(%d)\n", __func__, __LINE__);
- return 0;
- }
- static int ark_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
- {
- //struct snd_soc_component *component = dai->component;
- //struct ark_codec_priv *priv = snd_soc_component_get_drvdata(component);
- //unsigned int val = mute ? CODEC_REG_DAC_SOFT_MUTE : CODEC_REG_DAC_SOFT_UNMUTE;
- int ret = 0;
- #if 0
- printk("#####%s,%d:mute = %d\n", __func__, __LINE__, mute);
- if (mute) {
- regmap_update_bits(priv->regmap, CODEC_REG_PLAYBACK_MUTE,
- 0x3, 0x3);
- priv->mute_left = true;
- priv->mute_right = true;
- } else {
- regmap_update_bits(priv->regmap, CODEC_REG_PLAYBACK_MUTE,
- 0x3, 0x0);
- priv->mute_left = false;
- priv->mute_right = false;
- }
- #endif
- return ret;
- }
- static int ark_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
- unsigned int fmt)
- {
- //struct snd_soc_component *component = codec_dai->component;
- struct ark_codec_priv *priv = snd_soc_dai_get_drvdata(codec_dai);
- arkdbgprt("[ARK_CODEC] %s(%d),codec_dai->id = %d\n", __func__, __LINE__, codec_dai->id);
- /* set master/slave audio interface */
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
- case SND_SOC_DAIFMT_CBM_CFM:
- printk("###ark audio codec master###\n");
- //priv->master= 1;
- regmap_update_bits(priv->regmap, CODEC_REG_I2S1_CONFIG_0, CODEC_REG_I2S1_MODE_SEL, 0x1);
- break;
- case SND_SOC_DAIFMT_CBS_CFS:
- printk("###ark audio codec slave###\n");
- //priv->master = 0;
- regmap_update_bits(priv->regmap, CODEC_REG_I2S1_CONFIG_0, CODEC_REG_I2S1_MODE_SEL, 0x0);
- break;
- default:
- return -EINVAL;
- }
- return 0;
- }
- static const struct snd_soc_dai_ops ark_codec_dai_ops = {
- .startup = ark_codec_startup,
- .shutdown = ark_codec_shutdown,
- .hw_params = ark_codec_hw_params,
- .set_fmt = ark_codec_set_dai_fmt,
- .set_sysclk = ark_codec_set_dai_sysclk,
- .mute_stream = ark_codec_mute,
- };
- static struct snd_soc_dai_driver ark_codec_dai = {
- .name = "ark-codec-dai",
- .playback = {
- .stream_name = "Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = ARKADAC_RATES,
- .formats = ARKADAC_FORMATS,
- },
- .capture = {
- .stream_name = "Capture",
- .channels_min = 1,
- .channels_max = 4,
- .rates = ARKADAC_RATES,
- .formats = ARKADAC_FORMATS,
- },
- .ops = &ark_codec_dai_ops,
- .symmetric_rate = 1,
- };
- static int ark_codec_probe(struct snd_soc_component *component)
- {
- struct ark_codec_priv *priv = snd_soc_component_get_drvdata(component);
- ark_codec_component = component;
- priv->component = component;
- arkdbgprt("[ARK_CODEC] %s(%d)\n", __func__, __LINE__);
- ark_codec_init_reg(component);
- return 0;
- }
- static void ark_codec_remove(struct snd_soc_component *component)
- {
- //struct ark_codec_priv *priv = snd_soc_component_get_drvdata(component);
- arkdbgprt("[ARK_CODEC] %s(%d)\n", __func__, __LINE__);
- //regmap_write(priv->regmap, ADC_CODEC_REG_POWER_CTRL, 0);
- }
- static const struct snd_soc_component_driver ark_codec_component_driver = {
- .probe = ark_codec_probe,
- .remove = ark_codec_remove,
- .controls = ark_codec_controls,
- .num_controls = ARRAY_SIZE(ark_codec_controls),
- .dapm_widgets = dwc_audio_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(dwc_audio_dapm_widgets),
- // .dapm_routes = dwc_audio_dapm_routes,
- // .num_dapm_routes = ARRAY_SIZE(dwc_audio_dapm_routes),
- };
- static const struct regmap_config ark_codec_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = CODEC_REG_RESERVED_3,
- };
- static ssize_t ark_codec_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
- {
- int val = 0, flag = 0;
- u8 i = 0, reg, num, value_w;
- int value_r;
- struct ark_codec_priv *priv = dev_get_drvdata(dev);
- val = simple_strtol(buf, NULL, 16);
- flag = (val >> 16) & 0xFFF;
- if (flag) {
- reg = (val >> 8) & 0xFF;
- value_w = val & 0xFF;
- printk("\nWrite: start REG:0x%04x,val:0x%04x,count:0x%04x\n", reg, value_w, flag);
- while (flag--) {
- //ark_codec_write(ark_codec_component,reg, value_w);
- codec_reg_write(priv->i2c, reg, value_w);
- printk("Write 0x%04x to REG:0x%04x\n", value_w, reg);
- reg++;
- }
- } else {
- reg = (val >> 8) & 0xFF;
- num = val & 0xFF;
- printk("\nRead: start REG:0x%04x,count:0x%04x\n", reg, num);
- do {
- //value_r = 0;
- //value_r = ark_codec_read(ark_codec_component,reg);
- codec_reg_read(priv->i2c, reg, &value_r);
- printk("REG[0x%04x]: 0x%04x; ", reg, value_r);
- reg++;
- i++;
- if ((i == num) || (i%4 == 0))
- printk("\n");
- } while (i < num);
- }
- return count;
- }
- static ssize_t ark_codec_show(struct device *dev, struct device_attribute *attr, char *buf)
- {
- printk("echo flag|reg|val > ark_codec\n");
- printk("eg read star addres=0x06,count 0x10:echo 0610 >ark_codec\n");
- printk("eg write star addres=0x90,value=0x3c,count=4:echo 4903c >ark_codec\n");
- //printk("eg write value:0xfe to address:0x06 :echo 106fe > es7243\n");
- return 0;
- }
- static DEVICE_ATTR(ark_codec, 0644, ark_codec_show, ark_codec_store);
- static struct attribute *ark_codec_debug_attrs[] = {
- &dev_attr_ark_codec.attr,
- NULL,
- };
- static struct attribute_group ark_codec_debug_attr_group = {
- .name = "ark_codec_debug",
- .attrs = ark_codec_debug_attrs,
- };
- static int ark_codec_i2c_probe(struct i2c_client *i2c)
- {
- struct ark_codec_priv *priv;
- int ret;
- priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- priv->regmap = devm_regmap_init_i2c(i2c, &ark_codec_regmap_config);
- if (IS_ERR(priv->regmap))
- return PTR_ERR(priv->regmap);
- i2c_set_clientdata(i2c, priv);
- priv->i2c = i2c;
- ret = devm_snd_soc_register_component(&i2c->dev,
- &ark_codec_component_driver, &ark_codec_dai, 1);
- if (ret)
- dev_err(&i2c->dev, "Failed to register component: %d\n", ret);
- #if 1
- ret = sysfs_create_group(&i2c->dev.kobj, &ark_codec_debug_attr_group);
- if (ret) {
- pr_err("failed to create attr group\n");
- }
- #endif
- return ret;
- }
- static void ark_codec_i2c_remove(struct i2c_client *client)
- {
- }
- static void ark_codec_i2c_shutdown(struct i2c_client *client)
- {
- //struct ark_codec_priv *codec = i2c_get_clientdata(client);
- }
- static const struct i2c_device_id ark_codec_i2c_id[] = {
- { "ark-codec", 0 },
- { }
- };
- MODULE_DEVICE_TABLE(i2c, ark_codec_i2c_id);
- static const struct of_device_id ark_codec_of_match[] = {
- { .compatible = "arkmicro,ark-audio-codec" },
- { }
- };
- MODULE_DEVICE_TABLE(of, adc_codec_of_match);
- static struct i2c_driver ark_codec_i2c_driver = {
- .driver = {
- .name = "ark-codec",
- .of_match_table = ark_codec_of_match,
- },
- .probe = ark_codec_i2c_probe,
- .remove = ark_codec_i2c_remove,
- .shutdown = ark_codec_i2c_shutdown,
- .id_table = ark_codec_i2c_id,
- };
- module_i2c_driver(ark_codec_i2c_driver);
- MODULE_DESCRIPTION("ARK Codec I2C Driver");
- MODULE_AUTHOR("ARK");
- MODULE_LICENSE("GPL");
|