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

850 lines
34 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
*
* 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");