multimedia/device/mpp/extdrv/tlv320aic31/tlv320aic31.c

850 lines
34 KiB
C
Raw Normal View History

/*
*
* Copyright (c) 2006 Hisilicon Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* History:
* 10-April-2006 create this file
*/
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
#include <linux/slab.h>
//#include <linux/smp_lock.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <asm/io.h>
#include <asm/system.h>
#ifndef CONFIG_HISI_SNAPSHOT_BOOT
#include <linux/miscdevice.h>
#endif
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/poll.h>
#include <mach/hardware.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/notifier.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "tlv320aic31.h"
#include "tlv320aic31_def.h"
#ifdef CONFIG_HISI_SNAPSHOT_BOOT
#include "himedia.h"
#endif
#define CHIP_NUM 1
#define DEV_NAME "tlv320aic31"
#define DEBUG_LEVEL 1
#define DPRINTK(level,fmt,args...) do{ if(level < DEBUG_LEVEL)\
printk(KERN_INFO "%s [%s ,%d]: " fmt "\n",DEV_NAME,__FUNCTION__,__LINE__,##args);\
}while(0)
unsigned int IIC_device_addr[CHIP_NUM] = {0x30};
static struct i2c_board_info hi_info =
{
I2C_BOARD_INFO("tlv320aic31", 0x30),
};
static struct i2c_client* tlv_client;
static unsigned int open_cnt = 0;
static int chip_count = 1;
#ifdef CONFIG_HISI_SNAPSHOT_BOOT
static struct himedia_device s_stTlv320aic31Device;
#endif
static int tlv320aic31_device_init(unsigned int num);
int tlv320aic31_write(unsigned char chip_addr, unsigned char reg_addr, unsigned char value)
{
int ret;
unsigned char buf[2];
struct i2c_client* client = tlv_client;
buf[0] = reg_addr;
buf[1] = value;
ret = i2c_master_send(client, buf, 2);
return ret;
}
int tlv320aic31_read(unsigned char chip_addr, unsigned char reg_addr)
{
int ret_data = 0xFF;
int ret;
struct i2c_client* client = tlv_client;
unsigned char buf[2];
buf[0] = reg_addr;
ret = i2c_master_recv(client, buf, 1);
if (ret >= 0)
{
ret_data = buf[0];
}
return ret_data;
}
void tlv320aic31_reg_dump(unsigned int reg_num)
{
unsigned int i = 0;
for (i = 0; i < reg_num; i++)
{
printk("reg%d =%x,", i, tlv320aic31_read(IIC_device_addr[0], i));
if ((i + 1) % 8 == 0)
{
printk("\n");
}
}
}
void soft_reset(unsigned int chip_num)
{
/*soft reset*/
tlv320aic31_write(IIC_device_addr[chip_num], 0x1, 0x80);
msleep(10);
/*CLKDIV_IN uses MCLK*/
tlv320aic31_write(IIC_device_addr[chip_num], 102, 0x32);
#if 1
/*PLL disable and select Q value*/
tlv320aic31_write(IIC_device_addr[chip_num], 3, 0x10);
#else
/*PLL enable */
tlv320aic31_write(IIC_device_addr[chip_num], 3, 0x82);/* P=2 */
tlv320aic31_write(IIC_device_addr[chip_num], 4, 0x1c);/* J=28 */
tlv320aic31_write(IIC_device_addr[chip_num], 5, 0x2c);
tlv320aic31_write(IIC_device_addr[chip_num], 6, 0x8);/* reg 5 and 6 set D=2818*/
tlv320aic31_write(IIC_device_addr[chip_num], 11, 0x1);/* R=1 */
#endif
/*left and right DAC open*/
tlv320aic31_write(IIC_device_addr[chip_num], 7, 0xa);/* FSref = 48 kHz */
/*sample*/
tlv320aic31_write(IIC_device_addr[chip_num], 2, 0xaa);/* FS = FSref/6 */
/*ctrl mode*/
tlv320aic31_write(IIC_device_addr[chip_num], 8, 0xf0);/* master mode */
/*Audio Serial Data Interface Control*/
tlv320aic31_write(IIC_device_addr[chip_num], 9, 0x7);/* I2S mode,16bit */
/*Audio Codec Digital Filter Control Register*/
tlv320aic31_write(IIC_device_addr[chip_num], 12, 0x50);
//tlv320aic31_write(IIC_device_addr[chip_num], 25, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 25, 0x40);
tlv320aic31_write(IIC_device_addr[chip_num], 17, 0xf);
tlv320aic31_write(IIC_device_addr[chip_num], 18, 0xf0);
tlv320aic31_write(IIC_device_addr[chip_num], 15, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 16, 0x0);
//tlv320aic31_write(IIC_device_addr[chip_num], 19, 0x7c);
//tlv320aic31_write(IIC_device_addr[chip_num], 22, 0x7c);
tlv320aic31_write(IIC_device_addr[chip_num], 19, 0x04);
tlv320aic31_write(IIC_device_addr[chip_num], 22, 0x04);
tlv320aic31_write(IIC_device_addr[chip_num], 28, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 31, 0x0);
/*out ac-coupled*/
tlv320aic31_write(IIC_device_addr[chip_num], 14, 0x80);
/*left and right DAC power on*/
tlv320aic31_write(IIC_device_addr[chip_num], 37, 0xc0);
/*out common-mode voltage*/
//tlv320aic31_write(IIC_device_addr[chip_num], 40, 0x80);DTS2014123002762
/*out path select*/
tlv320aic31_write(IIC_device_addr[chip_num], 41, 0x1);
/*out path select DTS2014123002762 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>2s<32><73>Ϊ200ms*/
tlv320aic31_write(IIC_device_addr[chip_num], 42, 0x78);
/*left DAC not muted*/
tlv320aic31_write(IIC_device_addr[chip_num], 43, 0x0);
/*right DAC not muted*/
tlv320aic31_write(IIC_device_addr[chip_num], 44, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 47, 0x80);
/*HPLOUT is not muted*/
//tlv320aic31_write(IIC_device_addr[chip_num], 51, 0x04);
tlv320aic31_write(IIC_device_addr[chip_num], 64, 0x80);
/*HPROUT is not muted*/
//tlv320aic31_write(IIC_device_addr[chip_num], 65, 0x9f);
/*out short circuit protection*/
tlv320aic31_write(IIC_device_addr[chip_num], 38, 0x3e);
}
/*
* device open. set counter
*/
static int tlv320aic31_open(struct inode* inode, struct file* file)
{
if (0 == open_cnt++)
{
return 0;
}
return -1 ;
}
/*
* Close device, Do nothing!
*/
static int tlv320aic31_close(struct inode* inode , struct file* file)
{
open_cnt--;
return 0;
}
//static int tlv320aic31_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
static long tlv320aic31_ioctl(struct file* file, unsigned int cmd, unsigned long arg)
{
unsigned int __user* argp = (unsigned int __user*)arg;
unsigned int chip_num;
Audio_Ctrl temp;
Audio_Ctrl* audio_ctrl;
Codec_Datapath_Setup_Ctrl codec_datapath_setup_ctrl;
DAC_OUTPUT_SWIT_CTRL dac_output_swit_ctrl;
DAC_POWER_CTRL dac_power_ctrl;
In1_Adc_Ctrl in1_adc_ctrl ;
In2_Adc_Ctrl_Sample in2_adc_ctrl_sample ;
Adc_Pga_Dac_Gain_Ctrl adc_pga_dac_gain_ctrl;
Line_Hpcom_Out_Ctrl line_hpcom_out_ctrl;
Serial_Int_Ctrl serial_int_ctrl;
Serial_Data_Offset_Ctrl serial_data_offset_ctrl;
Ctrl_Mode ctrl_mode;
if (argp != NULL)
{
if (copy_from_user(&temp, argp, sizeof(Audio_Ctrl)))
{
return -EFAULT;
}
}
audio_ctrl = (Audio_Ctrl*)(&temp);
chip_num = audio_ctrl->chip_num;
switch (cmd)
{
case IN2LR_2_LEFT_ADC_CTRL:
in2_adc_ctrl_sample.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 17);
in2_adc_ctrl_sample.bit.in2l_adc_input_level_sample = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 17, in2_adc_ctrl_sample.b8);
break;
case IN2LR_2_RIGTH_ADC_CTRL:
in2_adc_ctrl_sample.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 18);
in2_adc_ctrl_sample.bit.in2r_adc_input_level_sample = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 18, in2_adc_ctrl_sample.b8);
break;
case IN1L_2_LEFT_ADC_CTRL:
in1_adc_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 19);
in1_adc_ctrl.bit.in1_adc_input_level = audio_ctrl->input_level;
in1_adc_ctrl.bit.adc_ch_power_ctrl = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 19, in1_adc_ctrl.b8);
break;
case IN1R_2_RIGHT_ADC_CTRL:
in1_adc_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 22);
in1_adc_ctrl.bit.in1_adc_input_level = audio_ctrl->input_level;
in1_adc_ctrl.bit.adc_ch_power_ctrl = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 22, in1_adc_ctrl.b8);
break;
case PGAL_2_HPLOUT_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 46);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 46, adc_pga_dac_gain_ctrl.b8);
break;
case DACL1_2_HPLOUT_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 47);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 47, adc_pga_dac_gain_ctrl.b8);
break;
case HPLOUT_OUTPUT_LEVEL_CTRL:
line_hpcom_out_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 51);
line_hpcom_out_ctrl.bit.if_mute = audio_ctrl->if_mute_route;
line_hpcom_out_ctrl.bit.output_level = audio_ctrl->input_level;
line_hpcom_out_ctrl.bit.power_status = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 51, line_hpcom_out_ctrl.b8);
break;
case PGAL_2_HPLCOM_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 53);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 53, adc_pga_dac_gain_ctrl.b8);
break;
case DACL1_2_HPLCOM_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 54);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 54, adc_pga_dac_gain_ctrl.b8);
break;
case HPLCOM_OUTPUT_LEVEL_CTRL:
line_hpcom_out_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 58);
line_hpcom_out_ctrl.bit.if_mute = audio_ctrl->if_mute_route;
line_hpcom_out_ctrl.bit.output_level = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 58, line_hpcom_out_ctrl.b8);
break;
case PGAR_2_HPROUT_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 63);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 63, adc_pga_dac_gain_ctrl.b8);
break;
case DACR1_2_HPROUT_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 64);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 64, adc_pga_dac_gain_ctrl.b8);
break;
case HPROUT_OUTPUT_LEVEL_CTRL:
line_hpcom_out_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 65);
line_hpcom_out_ctrl.bit.if_mute = audio_ctrl->if_mute_route;
line_hpcom_out_ctrl.bit.output_level = audio_ctrl->input_level;
line_hpcom_out_ctrl.bit.power_status = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 65, line_hpcom_out_ctrl.b8);
break;
case PGAR_2_HPRCOM_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 70);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 70, adc_pga_dac_gain_ctrl.b8);
break;
case DACR1_2_HPRCOM_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 71);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 71, adc_pga_dac_gain_ctrl.b8);
break;
case HPRCOM_OUTPUT_LEVEL_CTRL:
line_hpcom_out_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 72);
line_hpcom_out_ctrl.bit.if_mute = audio_ctrl->if_mute_route;
line_hpcom_out_ctrl.bit.output_level = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 72, line_hpcom_out_ctrl.b8);
break;
case PGAL_2_LEFT_LOP_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 81);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 81, adc_pga_dac_gain_ctrl.b8);
break;
case DACL1_2_LEFT_LOP_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 82);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 82, adc_pga_dac_gain_ctrl.b8);
break;
case LEFT_LOP_OUTPUT_LEVEL_CTRL:
line_hpcom_out_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 86);
line_hpcom_out_ctrl.bit.if_mute = audio_ctrl->if_mute_route;
line_hpcom_out_ctrl.bit.output_level = audio_ctrl->input_level;
line_hpcom_out_ctrl.bit.power_status = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 86, line_hpcom_out_ctrl.b8);
break;
case PGAR_2_RIGHT_LOP_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 91);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 91, adc_pga_dac_gain_ctrl.b8);
break;
case DACR1_2_RIGHT_LOP_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 92);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 92, adc_pga_dac_gain_ctrl.b8);
break;
case RIGHT_LOP_OUTPUT_LEVEL_CTRL:
line_hpcom_out_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 93);
line_hpcom_out_ctrl.bit.if_mute = audio_ctrl->if_mute_route;
line_hpcom_out_ctrl.bit.output_level = audio_ctrl->input_level;
line_hpcom_out_ctrl.bit.power_status = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 93, line_hpcom_out_ctrl.b8);
break;
case SET_ADC_SAMPLE:
in2_adc_ctrl_sample.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 2);
in2_adc_ctrl_sample.bit.in2l_adc_input_level_sample = audio_ctrl->sample;
tlv320aic31_write(IIC_device_addr[chip_num], 2, in2_adc_ctrl_sample.b8);
break;
case SET_DAC_SAMPLE:
in2_adc_ctrl_sample.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 2);
in2_adc_ctrl_sample.bit.in2r_adc_input_level_sample = audio_ctrl->sample;
tlv320aic31_write(IIC_device_addr[chip_num], 2, in2_adc_ctrl_sample.b8);
//printk("set SET_DAC_SAMPLE,audio_ctrl->sample=%x\n",audio_ctrl->sample);
break;
case SET_DATA_LENGTH:
serial_int_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 9);;
serial_int_ctrl.bit.data_length = audio_ctrl->data_length;
//tlv320aic31_write(IIC_device_addr[chip_num],9,serial_int_ctrl.b8);
break;
case SET_TRANSFER_MODE:
serial_int_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 9);
serial_int_ctrl.bit.transfer_mode = audio_ctrl->trans_mode;
tlv320aic31_write(IIC_device_addr[chip_num], 9, serial_int_ctrl.b8);
break;
case SET_CTRL_MODE:
//tlv320aic31_write(IIC_device_addr[chip_num],0x1,0x80);
//udelay(50);
ctrl_mode.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 8);
ctrl_mode.bit.bit_clock_dic_ctrl = audio_ctrl->ctrl_mode;
ctrl_mode.bit.work_clock_dic_ctrl = audio_ctrl->ctrl_mode;
ctrl_mode.bit.bit_work_dri_ctrl = audio_ctrl->ctrl_mode;
tlv320aic31_write(IIC_device_addr[chip_num], 8, ctrl_mode.b8);
#if 0
/* <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> */
if (1 == audio_ctrl->ctrl_mode
|| (AC31_SET_48K_SAMPLERATE != audio_ctrl->sample && AC31_SET_44_1K_SAMPLERATE != audio_ctrl->sample))
{
/* aic31<33><31><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD>߲<EFBFBD><DFB2><EFBFBD><EFBFBD>ʲ<EFBFBD>Ϊ44.1K/48KHZ<48><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>ⲿ<EFBFBD><E2B2BF>12.288MHZ<EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪMCLK<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD> */
if ((1 == audio_ctrl->if_44100hz_series))
{
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ44.1KHZϵ<EFBFBD>еIJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
tlv320aic31_write(IIC_device_addr[chip_num], 3, 0x81); /* P=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 4, 0x1c); /* J=7 */
tlv320aic31_write(IIC_device_addr[chip_num], 5, 0x36); /* reg 5 and 6 set D=3500*/
tlv320aic31_write(IIC_device_addr[chip_num], 6, 0xb0);
codec_datapath_setup_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 7);
codec_datapath_setup_ctrl.b8 |= 0x80; /* FSref = 44.1 kHz */
tlv320aic31_write(IIC_device_addr[chip_num], 7, codec_datapath_setup_ctrl.b8);
tlv320aic31_write(IIC_device_addr[chip_num], 11, 0x1); /* R=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 101, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 102, 0xc2);
}
else
{
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>44.1KHZϵ<EFBFBD>еIJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
tlv320aic31_write(IIC_device_addr[chip_num], 3, 0x81); /* P=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 4, 0x20); /* J=8 */
tlv320aic31_write(IIC_device_addr[chip_num], 5, 0x0); /* reg 5 and 6 set D=0000*/
tlv320aic31_write(IIC_device_addr[chip_num], 6, 0x0);
codec_datapath_setup_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 7);
codec_datapath_setup_ctrl.b8 &= 0x7f; /* FSref = 48 kHz */
tlv320aic31_write(IIC_device_addr[chip_num], 7, codec_datapath_setup_ctrl.b8);
tlv320aic31_write(IIC_device_addr[chip_num], 11, 0x1); /* R=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 101, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 102, 0xc2);
}
}
else
{
/* aic31<33><31><EFBFBD><EFBFBD>ģʽ<C4A3>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD>Ϊ44.1K/48KHZ<48><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD><C2A3><EFBFBD>BCLK<4C><4B><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> */
tlv320aic31_write(IIC_device_addr[chip_num], 102, 0x22); /* uses PLLCLK and BCLK */
codec_datapath_setup_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 7);
if ((1 == audio_ctrl->if_44100hz_series))
{
codec_datapath_setup_ctrl.b8 |= 0x80; /* FSref = 44.1 kHz */
}
else
{
codec_datapath_setup_ctrl.b8 &= 0x7f; /* FSref = 48 kHz */
}
tlv320aic31_write(IIC_device_addr[chip_num], 7, codec_datapath_setup_ctrl.b8);
tlv320aic31_write(IIC_device_addr[chip_num], 3, 0x81); /* P=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 4, 32 << 2); /* set PLL J to 32 */
tlv320aic31_write(IIC_device_addr[chip_num], 5, 0x0); /* reg 5 and 6 set D=0000*/
tlv320aic31_write(IIC_device_addr[chip_num], 6, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 101, 0x0); /* CODEC_CLKIN uses PLLDIV_OUT */
tlv320aic31_write(IIC_device_addr[chip_num], 11, 0x2); /* R = 2 */
}
#else
/* <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> */
/* aic31,<2C><>aiao<61>ṩmclk */
switch (audio_ctrl->sampleRate)
{
case 8000:
case 16000:
case 32000:
{
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ32KHZϵ<5A>еIJ<D0B5><C4B2><EFBFBD><EFBFBD><EFBFBD> */
tlv320aic31_write(IIC_device_addr[chip_num], 3, 0x81); /* P=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 4, 0x30); /* J=12 */
tlv320aic31_write(IIC_device_addr[chip_num], 5, 0x0); /* reg 5 and 6 set D=0000*/
tlv320aic31_write(IIC_device_addr[chip_num], 6, 0x0);
codec_datapath_setup_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 7);
codec_datapath_setup_ctrl.b8 &= 0x7f; /* FSref = 48 kHz */
tlv320aic31_write(IIC_device_addr[chip_num], 7, codec_datapath_setup_ctrl.b8);
tlv320aic31_write(IIC_device_addr[chip_num], 11, 0x1); /* R=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 101, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 102, 0xc2);
}
break;
case 12000:
case 24000:
case 48000:
{
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ48KHZϵ<5A>еIJ<D0B5><C4B2><EFBFBD><EFBFBD><EFBFBD> */
tlv320aic31_write(IIC_device_addr[chip_num], 3, 0x81); /* P=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 4, 0x20); /* J=8 */
tlv320aic31_write(IIC_device_addr[chip_num], 5, 0x0); /* reg 5 and 6 set D=0000*/
tlv320aic31_write(IIC_device_addr[chip_num], 6, 0x0);
codec_datapath_setup_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 7);
codec_datapath_setup_ctrl.b8 &= 0x7f; /* FSref = 48 kHz */
tlv320aic31_write(IIC_device_addr[chip_num], 7, codec_datapath_setup_ctrl.b8);
tlv320aic31_write(IIC_device_addr[chip_num], 11, 0x1); /* R=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 101, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 102, 0xc2);
}
break;
case 11025:
case 22050:
case 44100:
{
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ44.1KHZϵ<EFBFBD>еIJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
tlv320aic31_write(IIC_device_addr[chip_num], 3, 0x81); /* P=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 4, 0x20); /* J=7 */
tlv320aic31_write(IIC_device_addr[chip_num], 5, 0x00); /* reg 5 and 6 set D=0000*/
tlv320aic31_write(IIC_device_addr[chip_num], 6, 0x00);
codec_datapath_setup_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 7);
codec_datapath_setup_ctrl.b8 |= 0x80; /* FSref = 44.1 kHz */
tlv320aic31_write(IIC_device_addr[chip_num], 7, codec_datapath_setup_ctrl.b8);
tlv320aic31_write(IIC_device_addr[chip_num], 11, 0x1); /* R=1 */
tlv320aic31_write(IIC_device_addr[chip_num], 101, 0x0);
tlv320aic31_write(IIC_device_addr[chip_num], 102, 0xc2);
}
break;
default:
printk("aic31 unsupport sampleRate %d\n", audio_ctrl->sampleRate);
return -1;
}
#endif
break;
case LEFT_DAC_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 43);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 43, adc_pga_dac_gain_ctrl.b8);
break;
case RIGHT_DAC_VOL_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 44);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 44, adc_pga_dac_gain_ctrl.b8);
break;
case LEFT_DAC_POWER_SETUP:
codec_datapath_setup_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 7);
codec_datapath_setup_ctrl.bit.left_dac_datapath_ctrl = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 7, codec_datapath_setup_ctrl.b8);
dac_power_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 37);
dac_power_ctrl.bit.left_dac_power_ctrl = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 37, dac_power_ctrl.b8);
break;
case RIGHT_DAC_POWER_SETUP:
codec_datapath_setup_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 7);
codec_datapath_setup_ctrl.bit.right_dac_datapath_ctrl = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 7, codec_datapath_setup_ctrl.b8);
dac_power_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 37);
dac_power_ctrl.bit.right_dac_power_ctrl = audio_ctrl->if_powerup;
tlv320aic31_write(IIC_device_addr[chip_num], 37, dac_power_ctrl.b8);
break;
case DAC_OUT_SWITCH_CTRL:
dac_output_swit_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 41);
dac_output_swit_ctrl.bit.left_dac_swi_ctrl = audio_ctrl->dac_path;
dac_output_swit_ctrl.bit.right_dac_swi_ctrl = audio_ctrl->dac_path;
tlv320aic31_write(IIC_device_addr[chip_num], 41, dac_output_swit_ctrl.b8);
break;
case LEFT_ADC_PGA_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 15);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 15, adc_pga_dac_gain_ctrl.b8);
break;
case RIGHT_ADC_PGA_CTRL:
adc_pga_dac_gain_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 16);
adc_pga_dac_gain_ctrl.bit.if_mute_route = audio_ctrl->if_mute_route;
adc_pga_dac_gain_ctrl.bit.input_vol_level_ctrl = audio_ctrl->input_level;
tlv320aic31_write(IIC_device_addr[chip_num], 16, adc_pga_dac_gain_ctrl.b8);
break;
case SET_SERIAL_DATA_OFFSET:
serial_data_offset_ctrl.b8 = tlv320aic31_read(IIC_device_addr[chip_num], 10);
serial_data_offset_ctrl.bit.serial_data_offset = audio_ctrl->data_offset;
tlv320aic31_write(IIC_device_addr[chip_num], 10, serial_data_offset_ctrl.b8);
break;
case SOFT_RESET:
//printk("[Func]:%s [Line]:%d [Info]:%s\n", __FUNCTION__, __LINE__, "invalid attribute");
soft_reset(chip_num);
break;
case TLV320AIC31_REG_DUMP:
tlv320aic31_reg_dump(102);
break;
default:
break;
}
return 0;
}
#ifdef CONFIG_HISI_SNAPSHOT_BOOT
static int tlv320aic31_freeze(struct himedia_device* pdev)
{
printk(KERN_ALERT "%s %d\n", __FUNCTION__, __LINE__);
return 0;
}
static int tlv320aic31_restore(struct himedia_device* pdev)
{
int i;
for (i = 0; i < chip_count; i++)
{
if (tlv320aic31_device_init(i) < 0)
{
printk(KERN_ALERT "%s %d, tlv320aic31 device init fail!\n", __FUNCTION__, __LINE__);
return -1;
}
}
printk(KERN_ALERT "%s %d\n", __FUNCTION__, __LINE__);
return 0;
}
#endif
/*
* The various file operations we support.
*/
static struct file_operations tlv320aic31_fops =
{
.owner = THIS_MODULE,
.unlocked_ioctl = tlv320aic31_ioctl,
.open = tlv320aic31_open,
.release = tlv320aic31_close
};
#ifdef CONFIG_HISI_SNAPSHOT_BOOT
struct himedia_ops stTlv320aic31DrvOps =
{
.pm_freeze = tlv320aic31_freeze,
.pm_restore = tlv320aic31_restore
};
#else
static struct miscdevice tlv320aic31_dev =
{
MISC_DYNAMIC_MINOR,
DEV_NAME,
&tlv320aic31_fops,
};
#endif
static int set_chip_count(const char* val, const struct kernel_param* kp)
{
int ret;
int chip_count;
ret = kstrtoint(val, 10, &chip_count);
if (ret < 0)
{
return -EINVAL;
}
if (chip_count < 0 || chip_count > CHIP_NUM)
{
printk("chip_count%d err. \n", chip_count);
return -EINVAL;
}
return 0;
}
static struct kernel_param_ops alv320_para_ops =
{
.set = set_chip_count,
};
#if 0
module_param(chip_count, int, 0);
#else
module_param_cb(chip_count, &alv320_para_ops, &chip_count, 0644);
#endif
MODULE_PARM_DESC(chip_count, "the num we device uses the tlv320aic31,default 1");
static int tlv320aic31_reboot(struct notifier_block* self, unsigned long data, void* pdata)
{
unsigned int i;
for (i = 0; i < chip_count; i++)
{
/* HPLOUT is mute */
tlv320aic31_write(IIC_device_addr[i], 51, 0x04);
/* HPROUT is mute */
tlv320aic31_write(IIC_device_addr[i], 65, 0x04);
}
printk("Func:%s, line:%d######\n", __FUNCTION__, __LINE__);
return 0;
}
static struct notifier_block tlv320aic31_reboot_notifier =
{
.notifier_call = tlv320aic31_reboot,
};
static int tlv320aic31_device_init(unsigned int num)
{
/* inite codec configs.*/
unsigned char temp = 0;
temp = tlv320aic31_read(IIC_device_addr[num], 0x2);
tlv320aic31_write(IIC_device_addr[0], 0x2, 0xaa);
if ( tlv320aic31_read(IIC_device_addr[num], 0x2) != 0xaa)
{
DPRINTK(0, "init aic31(%d) error", num);
return -1;
}
tlv320aic31_write(IIC_device_addr[num], 0x2, temp);
soft_reset(num);
/* ע<><D7A2>reboot֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD> */
register_reboot_notifier(&tlv320aic31_reboot_notifier);
return 0;
}
static int tlv320aic31_device_exit(unsigned int num)
{
/* HPLOUT is mute */
tlv320aic31_write(IIC_device_addr[num], 51, 0x04);
/* HPROUT is mute */
tlv320aic31_write(IIC_device_addr[num], 65, 0x04);
return 0;
}
static int i2c_client_init(void)
{
struct i2c_adapter* i2c_adap;
// use i2c2
i2c_adap = i2c_get_adapter(2);
tlv_client = i2c_new_device(i2c_adap, &hi_info);
i2c_put_adapter(i2c_adap);
return 0;
}
static void i2c_client_exit(void)
{
i2c_unregister_device(tlv_client);
}
static int __init tlv320aic31_init(void)
{
unsigned int i, ret;
#ifdef CONFIG_HISI_SNAPSHOT_BOOT
snprintf(s_stTlv320aic31Device.devfs_name, sizeof(s_stTlv320aic31Device.devfs_name), DEV_NAME);
s_stTlv320aic31Device.minor = HIMEDIA_DYNAMIC_MINOR;
s_stTlv320aic31Device.fops = &tlv320aic31_fops;
s_stTlv320aic31Device.drvops = &stTlv320aic31DrvOps;
s_stTlv320aic31Device.owner = THIS_MODULE;
ret = himedia_register(&s_stTlv320aic31Device);
if (ret)
{
DPRINTK(0, "could not register tlv320aic31 device");
return -1;
}
#else
ret = misc_register(&tlv320aic31_dev);
if (ret)
{
DPRINTK(0, "could not register tlv320aic31 device");
return -1;
}
#endif
i2c_client_init();
for (i = 0; i < chip_count; i++)
{
if (tlv320aic31_device_init(i) < 0)
{
goto init_fail;
}
}
DPRINTK(1, "tlv320aic31 driver init successful!");
printk("load tlv320aic31.ko for Hi3518e ok!\n");
return ret;
init_fail:
#ifdef CONFIG_HISI_SNAPSHOT_BOOT
himedia_unregister(&s_stTlv320aic31Device);
#else
misc_deregister(&tlv320aic31_dev);
#endif
DPRINTK(0, "tlv320aic31 device init fail,deregister it!");
return -1;
}
static void __exit tlv320aic31_exit(void)
{
unsigned int i;
for (i = 0; i < chip_count; i++)
{
tlv320aic31_device_exit(i);
}
unregister_reboot_notifier(&tlv320aic31_reboot_notifier);
#ifdef CONFIG_HISI_SNAPSHOT_BOOT
himedia_unregister(&s_stTlv320aic31Device);
#else
misc_deregister(&tlv320aic31_dev);
#endif
i2c_client_exit();
DPRINTK(1, "deregister tlv320aic31");
printk("rmmod tlv320aic31.ko for Hi3518e ok!\n");
}
module_init(tlv320aic31_init);
module_exit(tlv320aic31_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Hisilicon");