[RK3399][Android7.1] 4通道ADC芯片ES7210驱动源码

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
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值