Platform: RK3399
OS: Android 7.1
Kernel: v4.4.83
说明:
内核里并没有关于ADC芯片ES7210的源码,驱动基于ES7243,分享给大家。
/*
* ALSA SoC ES7210 adc driver
*
* Author: David Yang, <yangxiaohua@everest-semi.com>
* Copyright: (C) 2018 Everest Semiconductor Co Ltd.,
*
* Based on sound/soc/codecs/es7243.c by David Yang
*
* 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.
*
* Notes:
* ES7210 is a 4-ch ADC of Everest
*
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/slab.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/tlv.h>
#include <sound/initval.h>
#include <linux/regmap.h>
#include "es7210.h"
#define ENABLE 1
#define DISABLE 0
#define MIC_CHN_16 16
#define MIC_CHN_14 14
#define MIC_CHN_12 12
#define MIC_CHN_10 10
#define MIC_CHN_8 8
#define MIC_CHN_6 6
#define MIC_CHN_4 4
#define MIC_CHN_2 2
#define ES7210_TDM_ENABLE ENABLE
#define ES7210_CHANNELS_MAX MIC_CHN_8
#if ES7210_CHANNELS_MAX == MIC_CHN_2
#define ADC_DEV_MAXNUM 1
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_4
#define ADC_DEV_MAXNUM 1
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_6
#define ADC_DEV_MAXNUM 2
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_8
#define ADC_DEV_MAXNUM 2
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_10
#define ADC_DEV_MAXNUM 3
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_12
#define ADC_DEV_MAXNUM 3
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_14
#define ADC_DEV_MAXNUM 4
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_16
#define ADC_DEV_MAXNUM 4
#endif
#define ES7210_TDM_1LRCK_DSPA 0
#define ES7210_TDM_1LRCK_DSPB 1
#define ES7210_TDM_1LRCK_I2S 2
#define ES7210_TDM_1LRCK_LJ 3
#define ES7210_TDM_NLRCK_DSPA 4
#define ES7210_TDM_NLRCK_DSPB 5
#define ES7210_TDM_NLRCK_I2S 6
#define ES7210_TDM_NLRCK_LJ 7
#define ES7210_WORK_MODE ES7210_TDM_NLRCK_I2S
#define ES7210_I2C_BUS_NUM 1
#define ES7210_CODEC_RW_TEST_EN 0
#define ES7210_IDLE_RESET_EN 1 //reset ES7210 when in idle time
#define ES7210_MATCH_DTS_EN 1 //ES7210 match method select: 0: i2c_detect, 1:of_device_id
struct i2c_client *i2c_clt1[ADC_DEV_MAXNUM];
/* codec private data */
struct es7210_priv {
struct regmap *regmap;
struct i2c_client *i2c;
unsigned int dmic_enable;
unsigned int sysclk;
struct clk *mclk;
struct snd_pcm_hw_constraint_list *sysclk_constraints;
unsigned int tdm_mode;
struct delayed_work pcm_pop_work;
};
struct snd_soc_codec *tron_codec1[ADC_DEV_MAXNUM];
int es7210_init_reg = 0;
static int es7210_codec_num = 0;
static const struct regmap_config es7210_regmap_config = {
.reg_bits = 8, //Number of bits in a register address
.val_bits = 8, //Number of bits in a register value
};
/*
* ES7210 register cache
*/
static const u8 es7210_reg[] = {
0x32, 0x40, 0x02, 0x04, 0x01, 0x00, 0x00, 0x20, /* 0 - 7 */
0x10, 0x40, 0x40, 0x00, 0x00, 0x09, 0x00, 0x00, /* 8 - F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10 - 17 */
0xf7, 0xf7, 0x00, 0xbf, 0xbf, 0xbf, 0xbf, 0x00, /* 18 - 1f */
0x26, 0x26, 0x06, 0x26, 0x00, 0x00, 0x00, 0x00, /* 20 - 27 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28 - 2f */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 - 37 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x10, 0x00, /* 38 - 3f */
0x80, 0x71, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 47 */
0x00, 0x00, 0x00, 0xff, 0xff, /* 48 - 4c */
};
static const struct reg_default es7210_reg_defaults[] = {
{ 0x00, 0x32 }, //0
{ 0x01, 0x40 },
{ 0x02, 0x02 },
{ 0x03, 0x04 },
{ 0x04, 0x01 },
{ 0x05, 0x00 },
{ 0x06, 0x00 },
{ 0x07, 0x20 },
{ 0x08, 0x10 },
{ 0x09, 0x40 },
{ 0x0a, 0x40 },
{ 0x0b, 0x00 },
{ 0x0c, 0x00 },
{ 0x0d, 0x09 },
{ 0x0e, 0x00 },
{ 0x0f, 0x00 },
{ 0x10, 0x00 },
{ 0x11, 0x00 },
{ 0x12, 0x00 },
{ 0x13, 0x00 },
{ 0x14, 0x00 },
{ 0x15, 0x00 },
{ 0x16, 0x00 },
{ 0x17, 0x00 },
{ 0x18, 0xf7 },
{ 0x19, 0xf7 },
{ 0x1a, 0x00 },
{ 0x1b, 0xbf },
{ 0x1c, 0xbf },
{ 0x1d, 0xbf },
{ 0x1e, 0xbf },
{ 0x1f, 0x00 },
{ 0x20, 0x26 },
{ 0x21, 0x26 },
{ 0x22, 0x06 },
{ 0x23, 0x26 },
{ 0x3d, 0x72 },
{ 0x3e, 0x10 },
{ 0x3f, 0x00 },
{ 0x40, 0x80 },
{ 0x41, 0x71 },
{ 0x42, 0x71 },
{ 0x43, 0x00 },
{ 0x44, 0x00 },
{ 0x45, 0x00 },
{ 0x46, 0x00 },
{ 0x47, 0x00 },
{ 0x48, 0x00 },
{ 0x49, 0x00 },
{ 0x4a, 0x00 },
{ 0x4b, 0xff },
{ 0x4c, 0xff },
};
struct es7210_reg_config {
unsigned char reg_addr;
unsigned char reg_v;
};
static const struct es7210_reg_config es7210_tdm_reg_common_cfg1[] = {
{ 0x00, 0xFF },
{ 0x00, 0x32 },
{ 0x09, 0x30 },
{ 0x0A, 0x30 },
{ 0x23, 0x26 },
{ 0x22, 0x06 },
{ 0x21, 0x26 },
{ 0x20, 0x06 },
};
static const struct es7210_reg_config es7210_tdm_reg_fmt_cfg[] = {
{ 0x11, 0x63 },
{ 0x12, 0x01 },
};
static const struct es7210_reg_config es7210_tdm_reg_common_cfg2[] = {
{ 0x40, 0xC3 },
{ 0x41, 0x70 },
{ 0x42, 0x70 },
{ 0x43, 0x1E },
{ 0x44, 0x1E },
{ 0x45, 0x1E },
{ 0x46, 0x1E },
{ 0x47, 0x08 },
{ 0x48, 0x08 },
{ 0x49, 0x08 },
{ 0x4A, 0x08 },
{ 0x07, 0x20 },
};
static const struct es7210_reg_config es7210_tdm_reg_mclk_cfg[] = {
{ 0x02, 0xC1 },
};
static const struct es7210_reg_config es7210_tdm_reg_common_cfg3[] = {
{ 0x06, 0x04 },
{ 0x4B, 0x0F },
{ 0x4C, 0x0F },
{ 0x00, 0x71 },
{ 0x00, 0x41 },
};
static int es7210_read(u8 reg, u8 *rt_value, struct i2c_client *client)
{
int ret;
u8 read_cmd[3] = {0};
u8 cmd_len = 0;
read_cmd[0] = reg;
cmd_len = 1;
if (client->adapter == NULL)
pr_err("es7210_read client->adapter==NULL\n");
ret = i2c_master_send(client, read_cmd, cmd_len);
if (ret != cmd_len) {
pr_err("es7210_read error1\n");
return -1;
}
ret = i2c_master_recv(client, rt_value, 1);
if (ret != 1) {
pr_err("es7210_read error2, ret = %d.\n", ret);
return -1;
}
return 0;
}
static int es7210_write(u8 reg, unsigned char value, struct i2c_client *client)
{
int ret = 0;
u8 write_cmd[2] = {0};
write_cmd[0] = reg;
write_cmd[1] = value;
ret = i2c_master_send(client, write_cmd, 2);
if (ret != 2) {
pr_err("es7210_write error->[REG-0x%02x,val-0x%02x]\n",reg,value);
return -1;
}
return 0;
}
static int es7210_update_bits(u8 reg, u8 mask, u8 value, struct i2c_client *client)
{
u8 val_old,val_new;
es7210_read(reg, &val_old, client);
val_new = (val_old & ~mask) | (value & mask);
if(val_new != val_old){
es7210_write(reg, val_new, client);
}
return 0;
}
/*
static int es7210_multi_chips_read(u8 reg, unsigned char *rt_value)
{
u8 i;
for(i=0; i< ADC_DEV_MAXNUM; i++){
es7210_read(reg, rt_value++, i2c_clt1[i]);
}
return 0;
}
*/
static int es7210_multi_chips_write(u8 reg, unsigned char value)
{
u8 i;
for(i=0; i< ADC_DEV_MAXNUM; i++){
es7210_write(reg, value, i2c_clt1[i]);
}
return 0;
}
static int es7210_multi_chips_update_bits(u8 reg, u8 mask, u8 value)
{
u8 i;
for(i=0; i< ADC_DEV_MAXNUM; i++){
es7210_update_bits(reg, mask, value, i2c_clt1[i]);
}
return 0;
}
/*
* Note that this should be called from init rather than from hw_params.
*/
static int es7210_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
return 0;
}
static int es7210_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
return 0;
}
/*
* to initialize es7210 for tdm mode
*/
static void es7210_tdm_init_codec(u8 mode)
{
int cnt, channel;
printk("begin->>>>>>>>>>%s!\n",__func__);
for(cnt = 0; cnt < sizeof(es7210_tdm_reg_common_cfg1)/sizeof(es7210_tdm_reg_common_cfg1[0]); cnt++) {
es7210_multi_chips_write(es7210_tdm_reg_common_cfg1[cnt].reg_addr,
es7210_tdm_reg_common_cfg1[cnt].reg_v);
}
switch(mode) {
case ES7210_TDM_1LRCK_DSPA:
/*
* Here to set TDM format for DSP-A mode
*/
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_write(ES7210_SDP_CFG1_REG11, 0x63, i2c_clt1[cnt]);
}
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_write(ES7210_SDP_CFG2_REG12, 0x01, i2c_clt1[cnt]);
}
break;
case ES7210_TDM_1LRCK_DSPB:
/*
* Here to set TDM format for DSP-B mode
*/
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_write(ES7210_SDP_CFG1_REG11, 0x73, i2c_clt1[cnt]);
}
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_write(ES7210_SDP_CFG2_REG12, 0x01, i2c_clt1[cnt]);
}
break;
case ES7210_TDM_1LRCK_I2S:
/*
* Here to set TDM format for I2S mode
*/
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_write(ES7210_SDP_CFG1_REG11, 0x60, i2c_clt1[cnt]);
}
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_write(ES7210_SDP_CFG2_REG12, 0x02, i2c_clt1[cnt]);
}
break;
case ES7210_TDM_1LRCK_LJ:
/*
* Here to set TDM format for Left Justified mode
*/
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_write(ES7210_SDP_CFG1_REG11, 0x61, i2c_clt1[cnt]);
}
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_write(ES7210_SDP_CFG2_REG12, 0x02, i2c_clt1[cnt]);
}
break;
case ES7210_TDM_NLRCK_DSPA:
/*
* Here to set TDM format for DSP-A with multiple LRCK TDM mode
*/
channel = ES7210_CHANNELS_MAX;
/*
* Set the microphone numbers in array
*/
switch(channel) {
case 2:
es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x10);
break;
case 4:
es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x20);
break;
case 6:
es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x30);
break;
case 8:
es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x40);
break;
case 10:
es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x50);
break;
case 12:
es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x60);
break;
case 14:
es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x70);
break;
case 16:
es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x80);
break;
default:
break;
}
/*
* set format, dsp-a with multiple LRCK tdm mode
*/
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_write(ES7210_SDP_CFG1_REG11, 0x63, i2c_clt1[c