1150 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1150 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * ALSA SoC ES7202 pdm adc driver
 | |
|  *
 | |
|  * Author:      David Yang, <yangxiaohua@everest-semi.com>
 | |
|  * Copyright:   (C) 2020 Everest Semiconductor Co Ltd.,
 | |
|  *
 | |
|  * Based on sound/soc/codecs/es7210.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:
 | |
|  *  ES7202 is 2-ch ADC with PDM interface
 | |
|  *
 | |
|  */
 | |
| #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/regulator/consumer.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 "es7202.h"
 | |
| 
 | |
| //static struct snd_soc_codec *es7202_codec;
 | |
| struct i2c_client *i2c_ctl[ADC_DEV_MAXNUM];
 | |
| struct snd_soc_component *tron_component1[ADC_DEV_MAXNUM];
 | |
| static int es7202_adc_num = 0;
 | |
| 
 | |
| /* codec private data */
 | |
| struct es7202_priv {
 | |
| 	struct regmap *regmap;
 | |
| 	struct i2c_client *i2c;
 | |
| 
 | |
| 	unsigned int pwr_vdd_voltage;
 | |
| 	struct regulator *vdd;
 | |
| 	int reset_gpio;
 | |
| 	bool reset_active_level;
 | |
| };
 | |
| 
 | |
| static const struct reg_default es7202_reg_defaults[] = {
 | |
| 	{0x00, 0x10}, {0x01, 0x00}, {0x02, 0x04}, {0x03, 0x00},
 | |
| 	{0x04, 0x01}, {0x05, 0x18}, {0x06, 0x00}, {0x07, 0x30},
 | |
| 	{0x08, 0x02}, {0x10, 0xff}, {0x11, 0x0c}, {0x12, 0x55},
 | |
| 	{0x13, 0x55}, {0x14, 0x8c}, {0x15, 0x33}, {0x16, 0x33},
 | |
| 	{0x17, 0x33}, {0x18, 0x44}, {0x19, 0x00}, {0x1a, 0x00},
 | |
| 	{0x1b, 0x00}, {0x1c, 0xf8}, {0x1d, 0x18}, {0x1e, 0x18},
 | |
| };
 | |
| 
 | |
| static int es7202_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 || !client->adapter)
 | |
| 		return -1;
 | |
| 
 | |
| 	ret = i2c_master_send(client, read_cmd, cmd_len);
 | |
| 	if (ret != cmd_len) {
 | |
| 		printk("es7202_read error1\n");
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	ret = i2c_master_recv(client, rt_value, 1);
 | |
| 	if (ret != 1) {
 | |
| 		printk("es7202_read error2, ret = %d.\n", ret);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_write(u8 reg, unsigned char value, struct i2c_client *client)
 | |
| {
 | |
| 	int ret = 0;
 | |
| 	u8 write_cmd[2] = { 0 };
 | |
| 
 | |
| 	if (!client || !client->adapter)
 | |
| 		return -1;
 | |
| 
 | |
| 	write_cmd[0] = reg;
 | |
| 	write_cmd[1] = value;
 | |
| 
 | |
| 	ret = i2c_master_send(client, write_cmd, 2);
 | |
| 	if (ret != 2) {
 | |
| 		printk("es7202_write error->[REG-0x%02x,val-0x%02x]\n",
 | |
| 		       reg, value);
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_update_bits(u8 reg, u8 mask, u8 value,
 | |
| 			      struct i2c_client *client)
 | |
| {
 | |
| 	u8 val_old = 0, val_new = 0;
 | |
| 
 | |
| 	es7202_read(reg, &val_old, client);
 | |
| 	val_new = (val_old & ~mask) | (value & mask);
 | |
| 	if (val_new != val_old) {
 | |
| 		es7202_write(reg, val_new, client);
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| #if 0
 | |
| static int es7202_multi_chips_write(u8 reg, unsigned char value)
 | |
| {
 | |
| 	u8 i;
 | |
| 
 | |
| 	for (i = 0; i < ADC_DEV_MAXNUM; i++) {
 | |
| 		es7202_write(reg, value, i2c_ctl[i]);
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| static int es7202_multi_chips_update_bits(u8 reg, u8 mask, u8 value)
 | |
| {
 | |
| 	u8 i;
 | |
| 
 | |
| 	for (i = 0; i < ADC_DEV_MAXNUM; i++) {
 | |
| 		es7202_update_bits(reg, mask, value, i2c_ctl[i]);
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, 0, 300, 0);
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 0
 | |
| static int es7202_micboost1_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 			struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1d, 0x0F,
 | |
| 		ucontrol->value.integer.value[0] & 0x0f, 
 | |
| 		i2c_ctl[0]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost1_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 			struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val = 0;
 | |
| 	es7202_read(0x1d, &val, i2c_ctl[0]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost2_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1e,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[0]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost2_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val = 0;
 | |
| 	es7202_read(0x1e, &val, i2c_ctl[0]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 2
 | |
| static int es7202_micboost3_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1d,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[1]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost3_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val = 0;
 | |
| 	es7202_read(0x1d, &val, i2c_ctl[1]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost4_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1e,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[1]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost4_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val = 0;
 | |
| 	es7202_read(0x1e, &val, i2c_ctl[1]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 4
 | |
| static int es7202_micboost5_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1d,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[2]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost5_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1d, &val, i2c_ctl[2]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost6_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1e,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[2]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost6_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1e, &val, i2c_ctl[2]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 6
 | |
| static int es7202_micboost7_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1d,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[3]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost7_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1d, &val, i2c_ctl[3]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost8_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1e,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[3]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost8_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1e, &val, i2c_ctl[3]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 8
 | |
| static int es7202_micboost9_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1d,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[4]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost9_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1d, &val, i2c_ctl[4]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost10_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1e,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[4]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost10_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1e, &val, i2c_ctl[4]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 10
 | |
| static int es7202_micboost11_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1d,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[5]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost11_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1d, &val, i2c_ctl[5]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost12_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1e,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[5]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost12_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1e, &val, i2c_ctl[5]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 12
 | |
| static int es7202_micboost13_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1d,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[6]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost13_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1d, &val, i2c_ctl[6]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost14_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1e,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[6]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost14_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1e, &val, i2c_ctl[6]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 14
 | |
| static int es7202_micboost15_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1d,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[7]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost15_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1d, &val, i2c_ctl[7]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost16_setting_set(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	es7202_update_bits(0x1e,
 | |
| 			   0x0F,
 | |
| 			   ucontrol->value.integer.value[0] & 0x0f, i2c_ctl[7]);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_micboost16_setting_get(struct snd_kcontrol *kcontrol,
 | |
| 					struct snd_ctl_elem_value *ucontrol)
 | |
| {
 | |
| 	u8 val;
 | |
| 	es7202_read(0x1e, &val, i2c_ctl[7]);
 | |
| 	ucontrol->value.integer.value[0] = val & 0x0f;
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static const struct snd_kcontrol_new es7202_snd_controls[] = {
 | |
| #if ES7202_CHANNELS_MAX > 0
 | |
| 	SOC_SINGLE_EXT_TLV("PGA1_setting", 0x1D, 0, 0x0C, 0,
 | |
| 			   es7202_micboost1_setting_get,
 | |
| 			   es7202_micboost1_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| 	SOC_SINGLE_EXT_TLV("PGA2_setting", 0x1E, 0, 0x0C, 0,
 | |
| 			   es7202_micboost2_setting_get,
 | |
| 			   es7202_micboost2_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 2
 | |
| 	SOC_SINGLE_EXT_TLV("PGA3_setting", 0x1D, 0, 0x0C, 0,
 | |
| 			   es7202_micboost3_setting_get,
 | |
| 			   es7202_micboost3_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| 	SOC_SINGLE_EXT_TLV("PGA4_setting", 0x1E, 0, 0x0C, 0,
 | |
| 			   es7202_micboost4_setting_get,
 | |
| 			   es7202_micboost4_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 4
 | |
| 	SOC_SINGLE_EXT_TLV("PGA5_setting", 0x1D, 0, 0x0C, 0,
 | |
| 			   es7202_micboost5_setting_get,
 | |
| 			   es7202_micboost5_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| 	SOC_SINGLE_EXT_TLV("PGA6_setting", 0x1E, 0, 0x0C, 0,
 | |
| 			   es7202_micboost6_setting_get,
 | |
| 			   es7202_micboost6_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 6
 | |
| 	SOC_SINGLE_EXT_TLV("PGA7_setting", 0x1D, 0, 0x0C, 0,
 | |
| 			   es7202_micboost7_setting_get,
 | |
| 			   es7202_micboost7_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| 	SOC_SINGLE_EXT_TLV("PGA8_setting", 0x1E, 0, 0x0C, 0,
 | |
| 			   es7202_micboost8_setting_get,
 | |
| 			   es7202_micboost8_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 8
 | |
| 	SOC_SINGLE_EXT_TLV("PGA9_setting", 0x1D, 0, 0x0C, 0,
 | |
| 			   es7202_micboost9_setting_get,
 | |
| 			   es7202_micboost9_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| 	SOC_SINGLE_EXT_TLV("PGA10_setting", 0x1E, 0, 0x0C, 0,
 | |
| 			   es7202_micboost10_setting_get,
 | |
| 			   es7202_micboost10_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 10
 | |
| 	SOC_SINGLE_EXT_TLV("PGA11_setting", 0x1D, 0, 0x0C, 0,
 | |
| 			   es7202_micboost11_setting_get,
 | |
| 			   es7202_micboost11_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| 	SOC_SINGLE_EXT_TLV("PGA12_setting", 0x1E, 0, 0x0C, 0,
 | |
| 			   es7202_micboost12_setting_get,
 | |
| 			   es7202_micboost12_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 12
 | |
| 	SOC_SINGLE_EXT_TLV("PGA13_setting", 0x1D, 0, 0x0C, 0,
 | |
| 			   es7202_micboost13_setting_get,
 | |
| 			   es7202_micboost13_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| 	SOC_SINGLE_EXT_TLV("PGA14_setting", 0x1E, 0, 0x0C, 0,
 | |
| 			   es7202_micboost14_setting_get,
 | |
| 			   es7202_micboost14_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 14
 | |
| 	SOC_SINGLE_EXT_TLV("PGA15_setting", 0x1D, 0, 0x0C, 0,
 | |
| 			   es7202_micboost15_setting_get,
 | |
| 			   es7202_micboost15_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| 	SOC_SINGLE_EXT_TLV("PGA16_setting", 0x1E, 0, 0x0C, 0,
 | |
| 			   es7202_micboost16_setting_get,
 | |
| 			   es7202_micboost16_setting_set,
 | |
| 			   mic_boost_tlv),
 | |
| #endif
 | |
| };
 | |
| 
 | |
| static int es7202_mute(struct snd_soc_dai *dai, int mute, int stream)
 | |
| {
 | |
| 	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
 | |
| 		return 0;
 | |
| 
 | |
| 	if (mute) {
 | |
| 		es7202_multi_chips_update_bits(ES7202_PDM_INF_CTL_REG07, 0x03,0x03);
 | |
| 	} else {
 | |
| 		es7202_multi_chips_update_bits(ES7202_PDM_INF_CTL_REG07, 0x03,0x00);
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| #define es7202_RATES SNDRV_PCM_RATE_8000_96000
 | |
| 
 | |
| static struct snd_soc_dai_ops es7202_ops = {
 | |
| 	.mute_stream = es7202_mute,
 | |
| };
 | |
| #if ES7202_CHANNELS_MAX > 0
 | |
| static struct snd_soc_dai_driver es7202_dai0 = {
 | |
| 	.name = "es7202 pdm 0",
 | |
| 	.capture = {
 | |
| 		.stream_name = "Capture",
 | |
| 		.channels_min = 1,
 | |
| 		.channels_max = 8,
 | |
| 		.rates = es7202_RATES,
 | |
| 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 | |
| 	},
 | |
| 	.ops = &es7202_ops,
 | |
| 	.symmetric_rate = 1,
 | |
| };
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 2
 | |
| static struct snd_soc_dai_driver es7202_dai1 = {
 | |
| 	.name = "es7202 pdm 1",
 | |
| 	.capture = {
 | |
| 		.stream_name = "Capture",
 | |
| 		.channels_min = 1,
 | |
| 		.channels_max = 8,
 | |
| 		.rates = es7202_RATES,
 | |
| 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 | |
| 	},
 | |
| 	.ops = &es7202_ops,
 | |
| 	.symmetric_rate = 1,
 | |
| };
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 4
 | |
| static struct snd_soc_dai_driver es7202_dai2 = {
 | |
| 	.name = "es7202 pdm 2",
 | |
| 	.capture = {
 | |
| 		.stream_name = "Capture",
 | |
| 		.channels_min = 1,
 | |
| 		.channels_max = 8,
 | |
| 		.rates = es7202_RATES,
 | |
| 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 | |
| 	},
 | |
| 	.ops = &es7202_ops,
 | |
| 	.symmetric_rate = 1,
 | |
| };
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 6
 | |
| static struct snd_soc_dai_driver es7202_dai3 = {
 | |
| 	.name = "es7202 pdm 3",
 | |
| 	.capture = {
 | |
| 		.stream_name = "Capture",
 | |
| 		.channels_min = 1,
 | |
| 		.channels_max = 8,
 | |
| 		.rates = es7202_RATES,
 | |
| 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 | |
| 	},
 | |
| 	.ops = &es7202_ops,
 | |
| 	.symmetric_rate = 1,
 | |
| };
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 8
 | |
| static struct snd_soc_dai_driver es7202_dai4 = {
 | |
| 	.name = "es7202 pdm 4",
 | |
| 	.capture = {
 | |
| 		.stream_name = "Capture",
 | |
| 		.channels_min = 1,
 | |
| 		.channels_max = 10,
 | |
| 		.rates = es7202_RATES,
 | |
| 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 | |
| 	},
 | |
| 	.ops = &es7202_ops,
 | |
| 	.symmetric_rate = 1,
 | |
| };
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 10
 | |
| static struct snd_soc_dai_driver es7202_dai5 = {
 | |
| 	.name = "es7202 pdm 5",
 | |
| 	.capture = {
 | |
| 		.stream_name = "Capture",
 | |
| 		.channels_min = 1,
 | |
| 		.channels_max = 12,
 | |
| 		.rates = es7202_RATES,
 | |
| 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 | |
| 	},
 | |
| 	.ops = &es7202_ops,
 | |
| 	.symmetric_rate = 1,
 | |
| };
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 12
 | |
| static struct snd_soc_dai_driver es7202_dai6 = {
 | |
| 	.name = "es7202 pdm 6",
 | |
| 	.capture = {
 | |
| 		.stream_name = "Capture",
 | |
| 		.channels_min = 1,
 | |
| 		.channels_max = 14,
 | |
| 		.rates = es7202_RATES,
 | |
| 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 | |
| 	},
 | |
| 	.ops = &es7202_ops,
 | |
| 	.symmetric_rate = 1,
 | |
| };
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 14
 | |
| static struct snd_soc_dai_driver es7202_dai7 = {
 | |
| 	.name = "es7202 pdm 7",
 | |
| 	.capture = {
 | |
| 		.stream_name = "Capture",
 | |
| 		.channels_min = 1,
 | |
| 		.channels_max = 16,
 | |
| 		.rates = es7202_RATES,
 | |
| 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 | |
| 	},
 | |
| 	.ops = &es7202_ops,
 | |
| 	.symmetric_rate = 1,
 | |
| };
 | |
| #endif
 | |
| 
 | |
| static struct snd_soc_dai_driver *es7202_dai[] = {
 | |
| #if ES7202_CHANNELS_MAX > 0
 | |
|         &es7202_dai0,
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 2
 | |
|         &es7202_dai1,
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 4
 | |
|         &es7202_dai2,
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 6
 | |
|         &es7202_dai3,
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 8
 | |
|         &es7202_dai4,
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 10
 | |
|         &es7202_dai5,
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 12
 | |
|         &es7202_dai6,
 | |
| #endif
 | |
| #if ES7202_CHANNELS_MAX > 14
 | |
|         &es7202_dai7,
 | |
| #endif
 | |
| };
 | |
| 
 | |
| static int es7202_suspend(struct snd_soc_component *component)
 | |
| {
 | |
| 	es7202_multi_chips_update_bits(ES7202_PDM_INF_CTL_REG07, 0x03,0x03);
 | |
| 	msleep(50);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_resume(struct snd_soc_component *component)
 | |
| {	
 | |
| 	msleep(50);
 | |
| 	es7202_multi_chips_update_bits(ES7202_PDM_INF_CTL_REG07, 0x03,0x00);
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int es7202_probe(struct snd_soc_component *component)
 | |
| {
 | |
| 	struct es7202_priv *es7202 = snd_soc_component_get_drvdata(component);
 | |
| 	int cnt;
 | |
| 	int ret = 0;
 | |
| 	printk("enter into %s()\n", __func__);
 | |
| 	tron_component1[es7202_adc_num++] = component;
 | |
| 
 | |
| 	for (cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
 | |
| 		es7202_write(ES7202_SOFT_MODE_REG01, 0x01, i2c_ctl[cnt]);
 | |
| 		switch(es7202->pwr_vdd_voltage) {
 | |
| 		case VDD_3V3:
 | |
| 			es7202_write(ES7202_ANALOG_MISC1_REG1B, 0x50, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_PGA1_REG1D, 0x1b, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_PGA2_REG1E, 0x1b, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_ANALOG_EN_REG10, 0x7F, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_BIAS_VMID_REG11, 0x2F, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_ANALOG_EN_REG10, 0x0F, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_ANALOG_EN_REG10, 0x00, i2c_ctl[cnt]);
 | |
| 			break;
 | |
| 		default:
 | |
| 		case VDD_1V8:
 | |
| 			es7202_write(ES7202_ANALOG_MISC1_REG1B, 0x40, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_PGA1_REG1D, 0x1b, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_PGA2_REG1E, 0x1b, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_ANALOG_EN_REG10, 0x7F, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_BIAS_VMID_REG11, 0x2F, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_ANALOG_EN_REG10, 0x3F, i2c_ctl[cnt]);
 | |
| 			es7202_write(ES7202_ANALOG_EN_REG10, 0x00, i2c_ctl[cnt]);
 | |
| 			break;	
 | |
| 		}
 | |
| 		es7202_write(ES7202_MOD1_BIAS_REG14, 0x58, i2c_ctl[cnt]);
 | |
| 		es7202_write(ES7202_CLK_DIV_REG02, 0x01, i2c_ctl[cnt]);
 | |
| 		es7202_write(ES7202_T2_VMID_REG05, 0x01, i2c_ctl[cnt]);
 | |
| 		es7202_write(ES7202_MISC_CTL_REG08, 0x02, i2c_ctl[cnt]);
 | |
| 		es7202_write(ES7202_RESET_REG00, 0x01, i2c_ctl[cnt]);
 | |
| 		es7202_write(ES7202_CLK_EN_REG03, 0x03, i2c_ctl[cnt]);
 | |
| 		es7202_write(ES7202_BIAS_VMID_REG11, 0x2E, i2c_ctl[cnt]);
 | |
| 
 | |
| 		es7202_multi_chips_update_bits(ES7202_PDM_INF_CTL_REG07, 0x03, 0x00);
 | |
| 	}
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| static void es7202_remove(struct snd_soc_component *component)
 | |
| {
 | |
| 	es7202_multi_chips_update_bits(ES7202_PDM_INF_CTL_REG07, 0x03,0x03);
 | |
| 	msleep(50);
 | |
| }
 | |
| 
 | |
| const struct regmap_config es7202_regmap_config = {
 | |
| 	.reg_bits	= 8,
 | |
| 	.val_bits	= 8,
 | |
| 	.max_register	= 0xff,
 | |
| 	.cache_type	= REGCACHE_RBTREE,
 | |
| 	.reg_defaults = es7202_reg_defaults,
 | |
| 	.num_reg_defaults = ARRAY_SIZE(es7202_reg_defaults),
 | |
| };
 | |
| 
 | |
| static struct snd_soc_component_driver soc_codec_dev_es7202 = {
 | |
| 	.probe =	es7202_probe,
 | |
| 	.remove =	es7202_remove,
 | |
| 	.suspend =	es7202_suspend,
 | |
| 	.resume =	es7202_resume,
 | |
| 	
 | |
| 	
 | |
| 	.controls = es7202_snd_controls,
 | |
| 	.num_controls = ARRAY_SIZE(es7202_snd_controls),
 | |
| 	.idle_bias_on = 1,
 | |
| 	.use_pmdown_time = 1,
 | |
| 	.endianness = 1,
 | |
| };
 | |
| 
 | |
| static ssize_t es7202_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, value_r;
 | |
| 	
 | |
| 	struct es7202_priv *es7202 = dev_get_drvdata(dev);
 | |
| 	val = simple_strtol(buf, NULL, 16);
 | |
| 	flag = (val >> 16) & 0xFF;
 | |
| 	
 | |
| 	if (flag) {
 | |
| 		reg = (val >> 8) & 0xFF;
 | |
| 		value_w = val & 0xFF;
 | |
| 		printk("\nWrite: start REG:0x%02x,val:0x%02x,count:0x%02x\n", reg, value_w, flag);
 | |
| 		while(flag--) {
 | |
| 			es7202_write(reg, value_w,  es7202->i2c);
 | |
| 			printk("Write 0x%02x to REG:0x%02x\n", value_w, reg);
 | |
| 			reg++;
 | |
| 		}
 | |
| 	} else {
 | |
| 		reg = (val >> 8) & 0xFF;
 | |
| 		num = val & 0xff;
 | |
| 		printk("\nRead: start REG:0x%02x,count:0x%02x\n", reg, num);
 | |
| 		do {
 | |
| 			value_r = 0;
 | |
| 			es7202_read(reg, &value_r, es7202->i2c);
 | |
| 			printk("REG[0x%02x]: 0x%02x;  ", reg, value_r);
 | |
| 			reg++;
 | |
| 			i++;
 | |
| 			if ((i==num) || (i%4==0))	printk("\n");
 | |
| 		} while (i<num);
 | |
| 	}
 | |
| 	
 | |
| 	return count;
 | |
| }
 | |
| 
 | |
| static ssize_t es7202_show(struct device *dev, struct device_attribute *attr, char *buf)
 | |
| {
 | |
| 	printk("echo flag|reg|val > es7202\n");
 | |
| 	printk("eg read star addres=0x06,count 0x10:echo 0610 >es7202\n");
 | |
| 	printk("eg write star addres=0x90,value=0x3c,count=4:echo 4903c >es7202\n");
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static DEVICE_ATTR(es7202, 0644, es7202_show, es7202_store);
 | |
| 
 | |
| static struct attribute *es7202_debug_attrs[] = {
 | |
| 	&dev_attr_es7202.attr,
 | |
| 	NULL,
 | |
| };
 | |
| 
 | |
| static struct attribute_group es7202_debug_attr_group = {
 | |
| 	.name   = "es7202_debug",
 | |
| 	.attrs  = es7202_debug_attrs,
 | |
| };
 | |
| 
 | |
| static int es7202_i2c_probe(struct i2c_client *i2c,
 | |
| 			    const struct i2c_device_id *id)
 | |
| {
 | |
| 	struct es7202_priv *es7202;
 | |
| 	int uV;
 | |
| 	int ret = -1;
 | |
| 
 | |
| 	dev_info(&i2c->dev, "probe\n");
 | |
| 	es7202 = devm_kzalloc(&i2c->dev, sizeof(*es7202), GFP_KERNEL);
 | |
| 	if (!es7202)
 | |
| 		return -ENOMEM;
 | |
| 	es7202->i2c = i2c;
 | |
| 	es7202->vdd = devm_regulator_get_optional(&i2c->dev, "power");
 | |
| 	if (IS_ERR(es7202->vdd)) {
 | |
| 		if (PTR_ERR(es7202->vdd) == -EPROBE_DEFER)
 | |
| 			return -EPROBE_DEFER;
 | |
| 		dev_warn(&i2c->dev, "power-supply get fail, use 3v3 as default\n");
 | |
| 		es7202->pwr_vdd_voltage = VDD_3V3;
 | |
| 	} else {
 | |
| 		uV = regulator_get_voltage(es7202->vdd);
 | |
| 		dev_info(&i2c->dev, "probe power-supply %duV\n", uV);
 | |
| 		if (uV <= MAX_VOLTAGE_1_8)
 | |
| 			es7202->pwr_vdd_voltage = VDD_1V8;
 | |
| 		else
 | |
| 			es7202->pwr_vdd_voltage = VDD_3V3;
 | |
| 	}
 | |
| 	dev_set_drvdata(&i2c->dev, es7202);
 | |
| 	if (id->driver_data < ADC_DEV_MAXNUM) {
 | |
| 		i2c_ctl[id->driver_data] = i2c;
 | |
| 		dev_info(&i2c->dev, "probe reigister es7202 dai(%s) component\n",
 | |
| 			 es7202_dai[id->driver_data]->name);
 | |
| 		ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_es7202,
 | |
| 						      es7202_dai[id->driver_data], 1);
 | |
| 		if (ret < 0) {
 | |
| 			return ret;
 | |
| 		}
 | |
| 	}
 | |
| 	ret = sysfs_create_group(&i2c->dev.kobj, &es7202_debug_attr_group);
 | |
| 	if (ret) {
 | |
| 		dev_err(&i2c->dev, "failed to create attr group\n");
 | |
| 	}
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| static void es7202_i2c_remove(struct i2c_client *client)
 | |
| {
 | |
| 	sysfs_remove_group(&client->dev.kobj, &es7202_debug_attr_group);
 | |
| }
 | |
| 
 | |
| static void es7202_i2c_shutdown(struct i2c_client *client)
 | |
| {
 | |
| 	es7202_multi_chips_update_bits(ES7202_PDM_INF_CTL_REG07, 0x03,0x03);
 | |
| 	msleep(50);
 | |
| }
 | |
| 
 | |
| #if !ES7202_MATCH_DTS_EN
 | |
| static int es7202_i2c_detect(struct i2c_client *client,
 | |
| 			     struct i2c_board_info *info)
 | |
| {
 | |
| 	struct i2c_adapter *adapter = client->adapter;
 | |
| 
 | |
| 	if (adapter->nr == ES7202_I2C_BUS_NUM) {
 | |
| 		if (client->addr == 0x30) {
 | |
| 			strlcpy(info->type, "ES7202_PDM_ADC_1", I2C_NAME_SIZE);
 | |
| 			return 0;
 | |
| 		} else if (client->addr == 0x31) {
 | |
| 			strlcpy(info->type, "ES7202_PDM_ADC_2", I2C_NAME_SIZE);
 | |
| 			return 0;
 | |
| 		} else if (client->addr == 0x32) {
 | |
| 			strlcpy(info->type, "ES7202_PDM_ADC_3", I2C_NAME_SIZE);
 | |
| 			return 0;
 | |
| 		} else if (client->addr == 0x33) {
 | |
| 			strlcpy(info->type, "ES7202_PDM_ADC_4", I2C_NAME_SIZE);
 | |
| 			return 0;
 | |
| 		}else if (client->addr == 0x34) {
 | |
| 			strlcpy(info->type, "ES7202_PDM_ADC_5", I2C_NAME_SIZE);
 | |
| 			return 0;
 | |
| 		}else if (client->addr == 0x35) {
 | |
| 			strlcpy(info->type, "ES7202_PDM_ADC_6", I2C_NAME_SIZE);
 | |
| 			return 0;
 | |
| 		}else if (client->addr == 0x36) {
 | |
| 			strlcpy(info->type, "ES7202_PDM_ADC_7", I2C_NAME_SIZE);
 | |
| 			return 0;
 | |
| 		}else if (client->addr == 0x37) {
 | |
| 			strlcpy(info->type, "ES7202_PDM_ADC_8", I2C_NAME_SIZE);
 | |
| 			return 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return -ENODEV;
 | |
| }
 | |
| 
 | |
| static const unsigned short es7202_i2c_addr[] = {
 | |
| #if ES7202_CHANNELS_MAX > 0
 | |
| 	0x30,
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 2
 | |
| 	0x31,
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 4
 | |
| 	0x32,
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 6
 | |
| 	0x33,
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 8
 | |
| 	0x34,
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 10
 | |
| 	0x35,
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 12
 | |
| 	0x36,
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 14
 | |
| 	0x37,
 | |
| #endif
 | |
| 	I2C_CLIENT_END,
 | |
| };
 | |
| #endif
 | |
| 
 | |
| #if ES7202_MATCH_DTS_EN
 | |
| /*
 | |
| * device tree source or i2c_board_info both use to 
 | |
| * transfer hardware information to linux kernel, 
 | |
| * use one of them wil be OK
 | |
| */
 | |
| #if 0
 | |
| static struct i2c_board_info es7202_i2c_board_info[] = {
 | |
| #if ES7202_CHANNELS_MAX > 0
 | |
| 	{I2C_BOARD_INFO("ES7202_PDM_ADC_1", 0x30),},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 2
 | |
| 	{I2C_BOARD_INFO("ES7202_PDM_ADC_2", 0x31),},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 4
 | |
| 	{I2C_BOARD_INFO("ES7202_PDM_ADC_3", 0x32),},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 6
 | |
| 	{I2C_BOARD_INFO("ES7202_PDM_ADC_4", 0x33),},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 8
 | |
| 	{I2C_BOARD_INFO("ES7202_PDM_ADC_5", 0x34),},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 10
 | |
| 	{I2C_BOARD_INFO("ES7202_PDM_ADC_6", 0x35),},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 12
 | |
| 	{I2C_BOARD_INFO("ES7202_PDM_ADC_7", 0x36),},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 14
 | |
| 	{I2C_BOARD_INFO("ES7202_PDM_ADC_8", 0x37),},
 | |
| #endif
 | |
| };
 | |
| #endif
 | |
| static const struct of_device_id es7202_dt_ids[] = {
 | |
| #if ES7202_CHANNELS_MAX > 0
 | |
| 	{.compatible = "ES7202_PDM_ADC_1",},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 2
 | |
| 	{.compatible = "ES7202_PDM_ADC_2",},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 4
 | |
| 	{.compatible = "ES7202_PDM_ADC_3",},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 6
 | |
| 	{.compatible = "ES7202_PDM_ADC_4",},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 8
 | |
| 	{.compatible = "ES7202_PDM_ADC_5",},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 10
 | |
| 	{.compatible = "ES7202_PDM_ADC_6",},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 12
 | |
| 	{.compatible = "ES7202_PDM_ADC_7",},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 14
 | |
| 	{.compatible = "ES7202_PDM_ADC_8",},
 | |
| #endif
 | |
| 	{}
 | |
| };
 | |
| #endif
 | |
| 
 | |
| static const struct i2c_device_id es7202_i2c_id[] = {
 | |
| #if ES7202_CHANNELS_MAX > 0
 | |
| 	{"ES7202_PDM_ADC_1", 0},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 2
 | |
| 	{"ES7202_PDM_ADC_2", 1},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 4
 | |
| 	{"ES7202_PDM_ADC_3", 2},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 6
 | |
| 	{"ES7202_PDM_ADC_4", 3},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 8
 | |
| 	{"ES7202_PDM_ADC_5", 4},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 10
 | |
| 	{"ES7202_PDM_ADC_6", 5},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 12
 | |
| 	{"ES7202_PDM_ADC_7", 6},
 | |
| #endif
 | |
| 
 | |
| #if ES7202_CHANNELS_MAX > 14
 | |
| 	{"ES7202_PDM_ADC_8", 7},
 | |
| #endif
 | |
| 	{}
 | |
| };
 | |
| 
 | |
| static struct i2c_driver es7202_i2c_driver = {
 | |
| 	.driver = {
 | |
| 		.name		= "es7202",
 | |
| #if ES7202_MATCH_DTS_EN
 | |
| 		   .of_match_table = es7202_dt_ids,
 | |
| #endif
 | |
| 	},
 | |
| 	.probe    = es7202_i2c_probe,
 | |
| 	.remove   = es7202_i2c_remove,
 | |
| 	.shutdown = es7202_i2c_shutdown,
 | |
| 	.class = I2C_CLASS_HWMON,
 | |
| 	.id_table = es7202_i2c_id,
 | |
| #if !ES7202_MATCH_DTS_EN
 | |
| 	.address_list = es7202_i2c_addr,
 | |
| 	.detect = es7202_i2c_detect,
 | |
| #endif	
 | |
| };
 | |
| 
 | |
| static int __init es7202_modinit(void)
 | |
| {
 | |
| 	int ret;
 | |
| //#if ES7202_MATCH_DTS_EN
 | |
| #if 0
 | |
| 	int i;
 | |
| 	struct i2c_adapter *adapter;
 | |
| 	struct i2c_client *client;
 | |
| #endif
 | |
| 
 | |
| //#if ES7202_MATCH_DTS_EN
 | |
| #if 0
 | |
| /*
 | |
| * Notes:
 | |
| * if the device has been declared in DTS tree,
 | |
| * here don't need to create new i2c device with i2c_board_info.
 | |
| */
 | |
| 	adapter = i2c_get_adapter(ES7202_I2C_BUS_NUM);
 | |
| 	if (!adapter) {
 | |
| 		printk("i2c_get_adapter() fail!\n");
 | |
| 		return -ENODEV;
 | |
| 	}
 | |
| 	printk("%s() begin0000", __func__);
 | |
| 
 | |
| 	for (i = 0; i < ADC_DEV_MAXNUM; i++) {
 | |
| 		client = i2c_new_device(adapter, &es7202_i2c_board_info[i]);
 | |
| 		printk("%s() i2c_new_device\n", __func__);
 | |
| 		if (!client)
 | |
| 			return -ENODEV;
 | |
| 	}
 | |
| 	i2c_put_adapter(adapter);
 | |
| #endif
 | |
| 	ret = i2c_add_driver(&es7202_i2c_driver);
 | |
| 	if (ret != 0)
 | |
| 		printk("Failed to register es7202 i2c driver : %d \n", ret);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| late_initcall(es7202_modinit);
 | |
| //module_init(es7202_modinit);
 | |
| static void __exit es7202_exit(void)
 | |
| {
 | |
| 	i2c_del_driver(&es7202_i2c_driver);
 | |
| }
 | |
| 
 | |
| module_exit(es7202_exit);
 | |
| 
 | |
| MODULE_DESCRIPTION("ASoC es7202 pdm adc driver");
 | |
| MODULE_AUTHOR(" David Yang, <yangxiaohua@everest-semi.com>>");
 | |
| MODULE_LICENSE("GPL v2");
 |