mirror of
https://github.com/hardkernel/linux.git
synced 2026-04-05 04:33:05 +09:00
Add codec wm8994
This commit is contained in:
@@ -341,7 +341,21 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = {
|
||||
.platform_data=&rk2818_pca9554_data.gpio_base,
|
||||
},
|
||||
#endif
|
||||
{}
|
||||
#if defined (CONFIG_SND_SOC_WM8994)
|
||||
{
|
||||
.type = "wm8994",
|
||||
.addr = 0x1a,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
#if defined (CONFIG_PMIC_LP8725)
|
||||
{
|
||||
.type = "lp8725",
|
||||
.addr = 0x79,
|
||||
.flags = 0,
|
||||
},
|
||||
#endif
|
||||
{},
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -115,4 +115,10 @@ config BATTERY_RK2818
|
||||
depends on RK28_ADC
|
||||
help
|
||||
Say Y to enable support for the battery on the RK2818.
|
||||
|
||||
config PMIC_LP8725
|
||||
tristate "pmic lp8725"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y to enable support for the pmic lp8725 on the RK2818.
|
||||
endif # POWER_SUPPLY
|
||||
|
||||
@@ -30,3 +30,4 @@ obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
|
||||
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
|
||||
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
|
||||
obj-$(CONFIG_BATTERY_RK2818) += rk2818_battery.o
|
||||
obj-$(CONFIG_PMIC_LP8725) += pmic_lp8725.o
|
||||
|
||||
780
drivers/power/pmic_lp8725.c
Normal file
780
drivers/power/pmic_lp8725.c
Normal file
@@ -0,0 +1,780 @@
|
||||
/* arch/arm/mach-rk2818/example.c
|
||||
*
|
||||
* Copyright (C) 2010 ROCKCHIP, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/*******************************************************************/
|
||||
/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED. */
|
||||
/*******************************************************************
|
||||
FILE : PCA9554.C
|
||||
DESC : <20><>չGPIO <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>س<EFBFBD><D8B3><EFBFBD>
|
||||
AUTHOR : ZHONGYW
|
||||
DATE : 2009-4-26
|
||||
NOTES :
|
||||
$LOG: GPIO.C,V $
|
||||
REVISION 0.01
|
||||
********************************************************************/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <linux/device.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <mach/board.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
#if 1
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define DBGERR(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBGERR(x...)
|
||||
#endif
|
||||
|
||||
#define DEFSEL_VIN1
|
||||
|
||||
#define GENERAL_REG_ADDR 0x0
|
||||
#define LDO1_REG_ADDR 0x01
|
||||
#define LDO2_REG_ADDR 0x02
|
||||
#define LDO3_REG_ADDR 0x03
|
||||
#define LDO4_REG_ADDR 0x04
|
||||
#define LDO5_REG_ADDR 0x05
|
||||
#define LILO1_REG_ADDR 0x06
|
||||
#define LILO2_REG_ADDR 0x07
|
||||
#define BUCK1_V1_REG_ADDR 0x08
|
||||
#define BUCK1_V2_REG_ADDR 0x09
|
||||
#define BUCK2_V1_REG_ADDR 0x0a
|
||||
#define BUCK2_V2_REG_ADDR 0x0b
|
||||
#define BUCK_CTR_REG_ADDR 0x0c
|
||||
#define LDO_CTR_REG_ADDR 0x0d
|
||||
#define PULLDOWN_REG_ADDR 0x0e
|
||||
#define STATUS_REG_ADDR 0x0f
|
||||
|
||||
#define LP8725_LDO_NUM 5
|
||||
#define LP8725_LILO_NUM 2
|
||||
#define LP8725_BUCK_NUM 2
|
||||
|
||||
|
||||
#define LDO_BUCKV1_TIME 5 //<2F><>3
|
||||
#define LDO_BUCKV_V 0 //<2F><>5
|
||||
#define BUCKV2_CL_BIT 6 //<2F><>2
|
||||
|
||||
#ifdef DEFSEL_VIN1
|
||||
#define GENERAL_REG_DEFAULT 0x59 //0101 1001 buck1output dependon dvs pin, dvs=1 v1 is used buck2v1 is output
|
||||
|
||||
#define LDO1_REG_T_DEFAULT 0x02 //1001 1001
|
||||
#define LDO1_REG_V_DEFAULT 0x19
|
||||
#define LDO2_REG_T_DEFAULT 0x04 //1001 1001
|
||||
#define LDO2_REG_V_DEFAULT 0x19
|
||||
#define LDO3_REG_T_DEFAULT 0x05 // 1011 1111
|
||||
#define LDO3_REG_V_DEFAULT 0x1f
|
||||
#define LDO4_REG_T_DEFAULT 0x04 // 1001 1101
|
||||
#define LDO4_REG_V_DEFAULT 0x1d
|
||||
#define LDO5_REG_T_DEFAULT 0x04 //1000 1100
|
||||
#define LDO5_REG_V_DEFAULT 0x0c
|
||||
|
||||
#define LILO1_REG_T_DEFAULT 0x05 //1010 1000
|
||||
#define LILO1_REG_V_DEFAULT 0x08
|
||||
#define LILO2_REG_T_DEFAULT 0x02 // 0101 0000
|
||||
#define LILO2_REG_V_DEFAULT 0x10
|
||||
|
||||
#define BUCK1_V1_REG_T_DEFAULT 0x00 // 0000 0100
|
||||
#define BUCK1_V1_REG_V_DEFAULT 0x04
|
||||
|
||||
#define BUCK1_V2_REG_C_DEFAULT 0x03 //1100 1000 <20>߶<EFBFBD>
|
||||
#define BUCK1_V2_REG_V_DEFAULT 0x08
|
||||
|
||||
#define BUCK2_V1_REG_T_DEFAULT 0x02 // 0101 0001
|
||||
#define BUCK2_V1_REG_V_DEFAULT 0x11
|
||||
|
||||
#define BUCK2_V2_REG_C_DEFAULT 0x02//1001 0001 <20>߶<EFBFBD>
|
||||
#define BUCK2_V2_REG_V_DEFAULT 0x11// <20><>5
|
||||
|
||||
#define BUCK2_CTR_REG_ADDR 0x11 // 0001 0001
|
||||
#define LDO_CTR_REG_DEFAULT 0x7f //0111 1111
|
||||
#define PULLDOWN_DEFAULT 0x7f //0111 1111
|
||||
#define STATUS_REG_DEFAULT 0x00 //0000 0000
|
||||
|
||||
#else
|
||||
|
||||
|
||||
|
||||
#define GENERAL_REG_DEFAULT 0x59 //0101 1001
|
||||
|
||||
#define LDO1_REG_T_DEFAULT 0x01 // 0011 0101
|
||||
#define LDO1_REG_V_DEFAULT 0x15
|
||||
#define LDO2_REG_T_DEFAULT 0x01 // 0011 1001
|
||||
#define LDO2_REG_V_DEFAULT 0x19
|
||||
|
||||
#define LDO3_REG_T_DEFAULT 0x02 // 0101 1001
|
||||
#define LDO3_REG_V_DEFAULT 0x19
|
||||
#define LDO4_REG_T_DEFAULT 0x02 // 0101 1001
|
||||
#define LDO4_REG_V_DEFAULT 0x19
|
||||
#define LDO5_REG_T_DEFAULT 0x01 // 0011 1001
|
||||
#define LDO5_REG_V_DEFAULT 0x19
|
||||
|
||||
#define LILO1_REG_T_DEFAULT 0x01 //0011 1111
|
||||
#define LILO1_REG_V_DEFAULT 0x1f
|
||||
|
||||
#define LILO2_REG_T_DEFAULT 0x00 // 0000 1000
|
||||
#define LILO2_REG_V_DEFAULT 0x08
|
||||
|
||||
#define BUCK1_V1_REG_T_DEFAULT 0x00 // 0000 1000
|
||||
#define BUCK1_V1_REG_V_DEFAULT 0x08
|
||||
|
||||
#define BUCK1_V2_REG_C_DEFAULT 0x03 //1100 0100 <20>߶<EFBFBD>
|
||||
#define BUCK1_V2_REG_V_DEFAULT 0x04
|
||||
|
||||
#define BUCK2_V1_REG_T_DEFAULT 0x01 // 0011 0001
|
||||
#define BUCK2_V1_REG_V_DEFAULT 0x11
|
||||
|
||||
#define BUCK2_V2_REG_C_DEFAULT 0x02 //1001 0001 <20>߶<EFBFBD>
|
||||
#define BUCK2_V2_REG_V_DEFAULT 0x11// <20><>5
|
||||
|
||||
#define BUCK_CTR_REG_ADDR 0x11 // 0001 0001
|
||||
#define LDO_CTR_REG_DEFAULT 0x7f //0111 1111
|
||||
#define PULLDOWN_REG_DEFAULT 0x7f //0111 1111
|
||||
#define STATUS_REG_DEFAULT 0x00 //0000 0000
|
||||
#endif
|
||||
|
||||
|
||||
struct i2c_client *lp8725_client;
|
||||
#define lp8725getbit(a,num) (((a)>>(num))&0x01)
|
||||
#define lp8725setbit(a,num) ((a)|(0x01<<(num)))
|
||||
#define lp8725clearbit(a,num) ((a)&(~(0x01<<(num))))
|
||||
|
||||
|
||||
static const struct i2c_device_id lp8725_id[] =
|
||||
{
|
||||
{ "lp8725", 0, },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, lp8725_id);
|
||||
|
||||
struct lp8725_regs_s
|
||||
{
|
||||
uint8_t general_reg_val;
|
||||
uint8_t ldo_reg_val[5];
|
||||
uint8_t lilo_reg_val[2];
|
||||
uint8_t buck_v1_reg_val[2];
|
||||
uint8_t buck_v2_reg_val[2];
|
||||
uint8_t buck_ctr_reg_val;
|
||||
uint8_t ldo_ctr_reg_val;
|
||||
uint8_t pulldown_reg_val;
|
||||
uint8_t status_reg_val;
|
||||
};
|
||||
struct lp8725_vol_range_s
|
||||
{
|
||||
uint16_t vol_low;
|
||||
uint16_t vol_high;
|
||||
uint16_t rang;
|
||||
};
|
||||
|
||||
|
||||
static struct lp8725_regs_s lp8725_regs;
|
||||
|
||||
|
||||
uint8_t ldo_reg_t_default[LP8725_LDO_NUM]={LDO1_REG_T_DEFAULT,LDO2_REG_T_DEFAULT,LDO3_REG_T_DEFAULT,LDO4_REG_T_DEFAULT,LDO5_REG_T_DEFAULT};
|
||||
uint8_t ldo_reg_v_default[LP8725_LDO_NUM]={LDO1_REG_V_DEFAULT,LDO2_REG_V_DEFAULT,LDO3_REG_V_DEFAULT,LDO4_REG_V_DEFAULT,LDO5_REG_V_DEFAULT};
|
||||
|
||||
uint8_t lilo_reg_t_default[LP8725_LILO_NUM]={LILO1_REG_T_DEFAULT,LILO2_REG_T_DEFAULT};
|
||||
uint8_t lilo_reg_v_default[LP8725_LILO_NUM]={LILO1_REG_V_DEFAULT,LILO2_REG_V_DEFAULT};
|
||||
|
||||
uint8_t buck_v1_reg_t_default[LP8725_BUCK_NUM]={BUCK1_V1_REG_T_DEFAULT,BUCK2_V1_REG_T_DEFAULT};
|
||||
uint8_t buck_v1_reg_v_default[LP8725_BUCK_NUM]={BUCK1_V1_REG_V_DEFAULT,BUCK2_V1_REG_V_DEFAULT};
|
||||
|
||||
uint8_t buck_v2_reg_c_default[LP8725_BUCK_NUM]={BUCK1_V2_REG_C_DEFAULT,BUCK2_V2_REG_C_DEFAULT};
|
||||
uint8_t buck_v2_reg_v_default[LP8725_BUCK_NUM]={BUCK1_V2_REG_V_DEFAULT,BUCK2_V2_REG_V_DEFAULT};
|
||||
|
||||
|
||||
#define LDO_RANG 5
|
||||
#define LILO_RANG 5
|
||||
#define BULK_RANG 6
|
||||
|
||||
struct lp8725_vol_range_s ldo_vol_range[LDO_RANG]={{120,190,5},{190,260,10},{260,300,5},{300,310,10},{310,330,20}};
|
||||
struct lp8725_vol_range_s lilo_vol_range[LILO_RANG]={{80,140,5},{140,280,10},{280,290,5},{290,310,10},{310,330,20}};
|
||||
struct lp8725_vol_range_s buck_vol_range[BULK_RANG]={{80,140,5},{140,170,10},{170,190,5},{190,280,10},{280,290,5},{290,300,10}};
|
||||
/* **********************************************************************
|
||||
* д<>Ĵ<EFBFBD><C4B4><EFBFBD>
|
||||
* return <0 failed
|
||||
* * ***********************************************************************/
|
||||
static int lp8725_write_reg(struct i2c_client *client, uint8_t reg, uint8_t val)
|
||||
{
|
||||
int ret=-1;
|
||||
DBG("**run in %s**\n",__FUNCTION__);
|
||||
struct i2c_adapter *adap;
|
||||
struct i2c_msg msg;
|
||||
char tx_buf[2];
|
||||
if(!client)
|
||||
return ret;
|
||||
adap = client->adapter;
|
||||
tx_buf[0] = reg;
|
||||
tx_buf[1]=val;
|
||||
//DBG("**run in %s**\n",__FUNCTION__);
|
||||
|
||||
msg.addr = client->addr;
|
||||
msg.buf = &tx_buf[0];
|
||||
msg.len = 1 +1;
|
||||
msg.flags = client->flags;
|
||||
msg.scl_rate = 200*1000;
|
||||
//DBG("**run in %s**\n",__FUNCTION__);
|
||||
|
||||
ret = i2c_transfer(adap, &msg, 1);
|
||||
//DBG("**run in %s**\n",__FUNCTION__);
|
||||
return ret;
|
||||
DBG("**run out %s**\n",__FUNCTION__);
|
||||
}
|
||||
/* **********************************************************************
|
||||
* <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>
|
||||
* return <0 failed
|
||||
* * ***********************************************************************/
|
||||
#if 1
|
||||
static int lp8725_read_reg(struct i2c_client *client, uint8_t reg, uint8_t *val)
|
||||
{
|
||||
|
||||
int ret;
|
||||
struct i2c_adapter *adap;
|
||||
struct i2c_msg msgs[2];
|
||||
if(!client)
|
||||
return ret;
|
||||
adap = client->adapter;
|
||||
//<2F><><EFBFBD>ͼĴ<CDBC><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ
|
||||
msgs[0].addr = client->addr;
|
||||
msgs[0].buf = ®
|
||||
msgs[0].flags = client->flags;
|
||||
msgs[0].len = 1;
|
||||
msgs[0].scl_rate = 200*1000;
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//msgs[1].buf = val;
|
||||
DBG("msgs[1].buf = %d\n",*msgs[1].buf);
|
||||
//msgs[1].buf = val;
|
||||
msgs[1].buf = val;
|
||||
msgs[1].addr = client->addr;
|
||||
msgs[1].flags = client->flags | I2C_M_RD;
|
||||
msgs[1].len = 1;
|
||||
msgs[1].scl_rate = 200*1000;
|
||||
|
||||
ret = i2c_transfer(adap, msgs, 2);
|
||||
//DBG("**has run at %s %d ret=%d**\n",__FUNCTION__,__LINE__,ret);
|
||||
DBG("msgs[1].buf = %d\n",*(msgs[1].buf));
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static int lp8725_read_reg(struct i2c_client *client, uint8_t reg)
|
||||
{
|
||||
|
||||
int ret;
|
||||
struct i2c_adapter *adap;
|
||||
struct i2c_msg msgs[2];
|
||||
if(!client)
|
||||
return ret;
|
||||
adap = client->adapter;
|
||||
//<2F><><EFBFBD>ͼĴ<CDBC><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ
|
||||
msgs[0].addr = client->addr;
|
||||
msgs[0].buf = ®
|
||||
msgs[0].flags = client->flags;
|
||||
msgs[0].len = 1;
|
||||
msgs[0].scl_rate = 200*1000;
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
msgs[1].buf;
|
||||
msgs[1].addr = client->addr;
|
||||
msgs[1].flags = client->flags | I2C_M_RD;
|
||||
msgs[1].len = 1;
|
||||
msgs[1].scl_rate = 200*1000;
|
||||
|
||||
ret = i2c_transfer(adap, msgs, 2);
|
||||
//DBG("**has run at %s %d ret=%d**\n",__FUNCTION__,__LINE__,ret);
|
||||
DBG("msgs[1].buf = %d\n",*msgs[1].buf);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/* **********************************************************************
|
||||
* <20><><EFBFBD><EFBFBD>ldo<64><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ
|
||||
*ldon:ldo<64><6F><EFBFBD><EFBFBD> <20><>ldo1 ldon=1<><31>vol <20><>ѹ<EFBFBD><D1B9>λ10mv <20><>1.2v vol=120
|
||||
*<2A><>ѹ<EFBFBD><D1B9>Χ:<3A><>1.2v<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>0.05v
|
||||
* return <0 failed
|
||||
* * ***********************************************************************/
|
||||
int lp8725_set_ldo_vol(uint8_t ldon,uint16_t vol)
|
||||
{
|
||||
|
||||
uint8_t val=0;
|
||||
uint8_t reg_val=0;
|
||||
int i;
|
||||
|
||||
if((vol>ldo_vol_range[LDO_RANG-1].vol_high)||(vol<ldo_vol_range[0].vol_low)||ldon>LP8725_LDO_NUM)
|
||||
return -1;
|
||||
|
||||
for(i=0;i<LDO_RANG;i++)
|
||||
{
|
||||
if(vol<=ldo_vol_range[i].vol_high)
|
||||
{
|
||||
val+=(vol-ldo_vol_range[i].vol_low)/ldo_vol_range[i].rang;
|
||||
break;
|
||||
}
|
||||
else
|
||||
val+=(ldo_vol_range[i].vol_high-ldo_vol_range[i].vol_low)/ldo_vol_range[i].rang;
|
||||
DBG("val=0x%x,vol=%d\n",val,vol);
|
||||
}
|
||||
|
||||
DBG("val=0x%x,vol=%d\n",val,vol);
|
||||
|
||||
reg_val=(ldo_reg_t_default[ldon-1]<<LDO_BUCKV1_TIME)|val;
|
||||
DBG("ldo_reg_t_default[ldon-1]=0x%x,LDO_BUCKV1_TIME=0x%x\n",ldo_reg_t_default[ldon-1],LDO_BUCKV1_TIME);
|
||||
DBG("ldo_reg_t_default[ldon-1]<<LDO_BUCKV1_TIME=0x%x\n",ldo_reg_t_default[ldon-1]<<LDO_BUCKV1_TIME);
|
||||
DBG("ADDR=0x%x,reg_val=0x%x\n",LDO1_REG_ADDR+ldon-1,reg_val);
|
||||
|
||||
if(lp8725_write_reg(lp8725_client,LDO1_REG_ADDR+ldon-1,reg_val)<0)
|
||||
{
|
||||
DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lp8725_regs.ldo_reg_val[ldon-1]=reg_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* **********************************************************************
|
||||
* <20><><EFBFBD><EFBFBD>lilo<6C><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ
|
||||
*ldon:ldo<64><6F><EFBFBD><EFBFBD> <20><>lilo1 lilon=1<><31>vol <20><>ѹ<EFBFBD><D1B9>λ10mv <20><>0.8v vol=80
|
||||
*<2A><>ѹ<EFBFBD><D1B9>Χ:<3A><>ѹ<EFBFBD><D1B9>[0.8,1.4]ʱ<><CAB1><EFBFBD><EFBFBD>0.05v<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD>[1.4,3.3]ʱ<><CAB1><EFBFBD><EFBFBD>0.1v
|
||||
* return <0 failed
|
||||
* * ***********************************************************************/
|
||||
int lp8725_set_lilo_vol(uint8_t lilon,uint16_t vol)
|
||||
{
|
||||
|
||||
uint8_t val=0;
|
||||
uint8_t reg_val=0;
|
||||
int i;
|
||||
|
||||
if((vol>lilo_vol_range[LILO_RANG-1].vol_high)||(vol<lilo_vol_range[0].vol_low)||lilon>LP8725_LILO_NUM)
|
||||
return -1;
|
||||
|
||||
for(i=0;i<LILO_RANG;i++)
|
||||
{
|
||||
if(vol<=lilo_vol_range[i].vol_high)
|
||||
{
|
||||
val+=(vol-lilo_vol_range[i].vol_low)/lilo_vol_range[i].rang;
|
||||
break;
|
||||
}
|
||||
else
|
||||
val+=(lilo_vol_range[i].vol_high-lilo_vol_range[i].vol_low)/lilo_vol_range[i].rang;
|
||||
}
|
||||
|
||||
reg_val=(lilo_reg_t_default[lilon-1]<<LDO_BUCKV1_TIME)|val;
|
||||
|
||||
if(lp8725_write_reg(lp8725_client,LILO1_REG_ADDR+lilon-1,reg_val)<0)
|
||||
{
|
||||
DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lp8725_regs.lilo_reg_val[lilon-1]=reg_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* **********************************************************************
|
||||
* <20><><EFBFBD><EFBFBD>buck<63><6B>v1 v2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD>ƼĴ<C6BC><C4B4><EFBFBD>
|
||||
*ldon:ldo<64><6F><EFBFBD><EFBFBD> <20><>buck1 buckn=1<><31>vol <20><>ѹ<EFBFBD><D1B9>λ10mv <20><>0.8v vol=80 <20><>v2=1 <20><><EFBFBD><EFBFBD>ѹֵд<D6B5><D0B4>v2 reg<65><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>v1 reg
|
||||
*<2A><>ѹ<EFBFBD><D1B9>Χ:<3A><>ѹ<EFBFBD><D1B9>[0.8,1.4]ʱ<><CAB1><EFBFBD><EFBFBD>0.05v<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD>[1.4,1.7]ʱ<><CAB1><EFBFBD><EFBFBD>0.1v<EFBFBD><EFBFBD>
|
||||
*<2A><>ѹ<EFBFBD><D1B9>[1.7,1.9]ʱ<><CAB1><EFBFBD><EFBFBD>0.05v<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD>[1.9,3.0]ʱ<><CAB1><EFBFBD><EFBFBD>0.1v
|
||||
* return <0 failed
|
||||
* * ***********************************************************************/
|
||||
static int lp8725_set_buck_vol_v1orv2(uint8_t buckn,uint16_t vol,uint8_t v2)
|
||||
{
|
||||
|
||||
uint8_t val=0;
|
||||
uint8_t reg_val=0;
|
||||
uint8_t reg_addr=0;
|
||||
int i;
|
||||
|
||||
if(vol>buck_vol_range[BULK_RANG-1].vol_high||vol<buck_vol_range[0].vol_low||buckn>LP8725_BUCK_NUM)
|
||||
return -1;
|
||||
|
||||
for(i=0;i<BULK_RANG;i++)
|
||||
{
|
||||
if(vol<=buck_vol_range[i].vol_high)
|
||||
{
|
||||
val+=(vol-buck_vol_range[i].vol_low)/buck_vol_range[i].rang;
|
||||
break;
|
||||
}
|
||||
else
|
||||
val+=(buck_vol_range[i].vol_high-buck_vol_range[i].vol_low)/buck_vol_range[i].rang;
|
||||
}
|
||||
|
||||
reg_addr=BUCK1_V1_REG_ADDR+(buckn-1)*2;
|
||||
reg_val=(buck_v1_reg_t_default[buckn-1]<<LDO_BUCKV1_TIME)|val;
|
||||
|
||||
if(v2)
|
||||
reg_addr=BUCK1_V2_REG_ADDR+(buckn-1)*2;
|
||||
|
||||
|
||||
if(lp8725_write_reg(lp8725_client,reg_addr,reg_val)<0)
|
||||
{
|
||||
DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(v2)
|
||||
lp8725_regs.buck_v2_reg_val[buckn-1]=reg_val;
|
||||
else
|
||||
lp8725_regs.buck_v1_reg_val[buckn-1]=reg_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/***************************************************************
|
||||
*
|
||||
*
|
||||
****************************************************************/
|
||||
int lp8725_set_buck_dvsn_v_bit(uint8_t buckn,uint8_t dvs)
|
||||
{
|
||||
|
||||
|
||||
uint8_t reg_val=0;
|
||||
|
||||
if(dvs)
|
||||
reg_val=lp8725_regs.general_reg_val|(0x01<<(2+buckn-1));
|
||||
else
|
||||
reg_val=lp8725_regs.general_reg_val&(~0x01<<(12+buckn-1));
|
||||
|
||||
|
||||
if(lp8725_write_reg(lp8725_client,GENERAL_REG_ADDR,reg_val)<0)
|
||||
{
|
||||
|
||||
DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lp8725_regs.general_reg_val=reg_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* **********************************************************************
|
||||
* <20><><EFBFBD><EFBFBD>buck<63><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ
|
||||
*ldon:ldo<64><6F><EFBFBD><EFBFBD> <20><>buck1 buckn=1<><31>vol <20><>ѹ<EFBFBD><D1B9>λ10mv <20><>0.8v vol=80
|
||||
*<2A><>ѹ<EFBFBD><D1B9>Χ:<3A><>ѹ<EFBFBD><D1B9>[0.8,1.4]ʱ<><CAB1><EFBFBD><EFBFBD>0.05v<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD>[1.4,1.7]ʱ<><CAB1><EFBFBD><EFBFBD>0.1v<EFBFBD><EFBFBD>
|
||||
*<2A><>ѹ<EFBFBD><D1B9>[1.7,1.9]ʱ<><CAB1><EFBFBD><EFBFBD>0.05v<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD>[1.9,3.0]ʱ<><CAB1><EFBFBD><EFBFBD>0.1v
|
||||
*ÿ<><C3BF>buck <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>v1<76><31>v2<76><32>buck <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD><C7B8>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ
|
||||
* buck1: dvs1_v=1 output vol depend on buck1_v1 reg,else depend on dvs pin. dvspin=1 output vol depend on buck1_v1,esle output vol depend on buck1_v2
|
||||
*buck2:dvs1_v=1 output vol depend on buck2_v1 reg,else depend on buck2_v2.
|
||||
* return <0 failed
|
||||
* * ***********************************************************************/
|
||||
|
||||
int lp8725_set_buck_vol(uint8_t buckn,uint16_t vol)
|
||||
{
|
||||
|
||||
if(lp8725_set_buck_vol_v1orv2(buckn,vol,0)<0)
|
||||
return -1;
|
||||
|
||||
return lp8725_set_buck_vol_v1orv2(buckn,vol,1);
|
||||
|
||||
}
|
||||
|
||||
int get_dvs_pin_level(void)
|
||||
{
|
||||
|
||||
// dvs pin is low return 0
|
||||
|
||||
}
|
||||
int set_dvs_pin_level(uint8_t level)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
*in sleep mode all pins val is low
|
||||
*reg SLEEP_MODE=0,and pin DVS=0<><30>this ic enter into seelp mode
|
||||
********************************************************************************/
|
||||
int lp8725_setinto_sleep(uint8_t sleep)
|
||||
{
|
||||
|
||||
|
||||
uint8_t reg_val=0;
|
||||
set_dvs_pin_level(0);
|
||||
|
||||
if(sleep)
|
||||
reg_val=lp8725_regs.general_reg_val|(0x01<<1);
|
||||
else
|
||||
reg_val=lp8725_regs.general_reg_val&(~0x01<<1);
|
||||
if(lp8725_write_reg(lp8725_client,GENERAL_REG_ADDR,reg_val)<0)
|
||||
{
|
||||
|
||||
DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
lp8725_regs.general_reg_val=reg_val;
|
||||
return 0;
|
||||
}
|
||||
/***************************************************************
|
||||
*
|
||||
*
|
||||
****************************************************************/
|
||||
int lp8725_buck_en(uint8_t buckn,uint8_t enble)
|
||||
{
|
||||
|
||||
|
||||
uint8_t reg_val=0;
|
||||
|
||||
if(buckn==1)
|
||||
{
|
||||
if(enble)
|
||||
reg_val=lp8725_regs.general_reg_val|0x01;
|
||||
else
|
||||
reg_val=lp8725_regs.general_reg_val&(~0x01);
|
||||
}
|
||||
|
||||
if(buckn==2)
|
||||
{
|
||||
if(enble)
|
||||
reg_val=lp8725_regs.general_reg_val|(0x01<<4);
|
||||
else
|
||||
reg_val=lp8725_regs.general_reg_val&(~0x01<<4);
|
||||
}
|
||||
|
||||
if(lp8725_write_reg(lp8725_client,GENERAL_REG_ADDR,reg_val)<0)
|
||||
{
|
||||
|
||||
DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lp8725_regs.general_reg_val=reg_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int lp8725_lilo_en(uint8_t lilon,uint8_t enble)
|
||||
{
|
||||
uint8_t reg_val=0;
|
||||
|
||||
if(enble)
|
||||
reg_val=lp8725_regs.ldo_ctr_reg_val|(0x01<<(5+lilon-1));
|
||||
else
|
||||
reg_val=lp8725_regs.ldo_ctr_reg_val&(~(0x01<<(5+lilon-1)));
|
||||
|
||||
if(lp8725_write_reg(lp8725_client,LDO_CTR_REG_ADDR,reg_val)<0)
|
||||
{
|
||||
|
||||
DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lp8725_regs.ldo_ctr_reg_val=reg_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/***************************************************************
|
||||
*ldo3 is enbale if pin LdO3_EN=1 or LDO3 enable reg=1
|
||||
*
|
||||
****************************************************************/
|
||||
int lp8725_ldo_en(uint8_t ldo,uint8_t enble)
|
||||
{
|
||||
|
||||
|
||||
uint8_t reg_val=0;
|
||||
|
||||
if(enble)
|
||||
reg_val=lp8725_regs.ldo_ctr_reg_val|(0x01<<(ldo-1));
|
||||
else
|
||||
reg_val=lp8725_regs.ldo_ctr_reg_val&(~(0x01<<(ldo-1)));
|
||||
|
||||
|
||||
if(lp8725_write_reg(lp8725_client,LDO_CTR_REG_ADDR,reg_val)<0)
|
||||
{
|
||||
DBGERR("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
lp8725_regs.ldo_ctr_reg_val=reg_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void lp8725_set_init(void)
|
||||
{
|
||||
|
||||
uint8_t reg_val=0;
|
||||
uint8_t read_ret;
|
||||
lp8725_regs.general_reg_val=GENERAL_REG_DEFAULT;
|
||||
lp8725_regs.buck_ctr_reg_val=BUCK_CTR_REG_ADDR;
|
||||
lp8725_regs.pulldown_reg_val=PULLDOWN_REG_ADDR;
|
||||
lp8725_regs.status_reg_val=STATUS_REG_ADDR;
|
||||
/*
|
||||
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ldo 1<><31>2<EFBFBD><32>5 lilo2Ĭ<32><C4AC>Ϊ<EFBFBD>ر<EFBFBD>
|
||||
*/
|
||||
DBG("**run in %s**\n",__FUNCTION__);
|
||||
//reg_val=LDO_CTR_REG_ADDR&&(~(1<<0))&&(~(1<<0))&&(~(1<<1))&&(~(1<<4))&&(~(1<<6));
|
||||
reg_val=0x7f;
|
||||
DBG("**lp8725_client=%s**LDO_CTR_REG_ADDR=%d**reg_val=%d\n",lp8725_client,LDO_CTR_REG_ADDR,reg_val);
|
||||
if(lp8725_write_reg(lp8725_client,LDO_CTR_REG_ADDR,reg_val)<0)
|
||||
{
|
||||
DBG("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
**set ldo4 VCCA 3.3V;ldo5 AVDD18 1.8v
|
||||
*/
|
||||
lp8725_set_ldo_vol(4,330);
|
||||
lp8725_set_ldo_vol(5,180);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
DBG("**begin lp8725_read_reg %s %d \n",__FUNCTION__,__LINE__);
|
||||
if(lp8725_read_reg(lp8725_client,0x00,&read_ret)<0)
|
||||
{
|
||||
DBG("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
DBG("**lp8725_read_reg %s %d return read_ret = %d\n",__FUNCTION__,__LINE__,read_ret);
|
||||
#endif
|
||||
|
||||
lp8725_regs.ldo_ctr_reg_val=reg_val;
|
||||
|
||||
DBG("**run out %s**\n",__FUNCTION__);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static __init int seqgen1_init(void)
|
||||
{
|
||||
uint8_t *read_val;
|
||||
//uint8_t reg_val=0x98;
|
||||
DBG("**************run in %s\n",__FUNCTION__);
|
||||
//lp8725_set_ldo_vol(2,150);
|
||||
//lp8725_set_lilo_vol(2,150);
|
||||
//lp8725_set_buck_vol(2,170);
|
||||
|
||||
while(1)
|
||||
{
|
||||
DBG("\n***lp8725_lilo_en(2,0)\n");
|
||||
lp8725_lilo_en(2,0);
|
||||
mdelay(6000);
|
||||
DBG("\n***lp8725_lilo_en(2,1)\n");
|
||||
lp8725_lilo_en(2,1);
|
||||
mdelay(6000);
|
||||
}
|
||||
|
||||
#if 0
|
||||
while(1)
|
||||
{
|
||||
int i;
|
||||
for(i=180;i<=330;i=i-10)
|
||||
{
|
||||
DBG("\n\n**i=%d\n",i);
|
||||
DBG("**************run in %s\n",__FUNCTION__);
|
||||
lp8725_set_buck_vol(2,i);
|
||||
mdelay(3000);
|
||||
}
|
||||
}
|
||||
DBG("**************run out %s\n",__FUNCTION__);
|
||||
|
||||
|
||||
if(lp8725_write_reg(lp8725_client,LDO2_REG_ADDR,reg_val)<0)
|
||||
{
|
||||
DBG("%s %d error\n",__FUNCTION__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
lp8725_read_reg(lp8725_client,LDO_CTR_REG_ADDR,read_val);
|
||||
DBG("\n*****read_val = %d\n",read_val);
|
||||
}
|
||||
DBG("**************run out %s\n",__FUNCTION__);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
late_initcall(seqgen1_init);
|
||||
#endif
|
||||
|
||||
|
||||
static int __devinit lp8725_probe(struct i2c_client *client,const struct i2c_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DBG("**%s in %d line,dev adr is %x**\n",__FUNCTION__,__LINE__,client->addr);
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
return -EIO;
|
||||
lp8725_client=client;
|
||||
lp8725_set_init();
|
||||
|
||||
DBG("**run out %s**\n",__FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp8725_remove(struct i2c_client *client)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver lp8725_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "lp8725",
|
||||
},
|
||||
.probe = lp8725_probe,
|
||||
.remove = lp8725_remove,
|
||||
.id_table = lp8725_id,
|
||||
};
|
||||
|
||||
static int __init lp8725_init(void)
|
||||
{
|
||||
int ret;
|
||||
ret = i2c_add_driver(&lp8725_driver);
|
||||
DBG("**lp8725_init return %d**\n",ret);
|
||||
return ret;
|
||||
}
|
||||
static void __exit lp8725_exit(void)
|
||||
{
|
||||
i2c_del_driver(&lp8725_driver);
|
||||
}
|
||||
|
||||
module_init(lp8725_init);
|
||||
module_exit(lp8725_exit);
|
||||
MODULE_AUTHOR(" XXX XXX@rock-chips.com");
|
||||
MODULE_DESCRIPTION("Driver for rk2818 extend gpio device");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ config SND_SOC_ALL_CODECS
|
||||
select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
|
||||
select SND_SOC_WM8990 if I2C
|
||||
select SND_SOC_WM8993 if I2C
|
||||
select SND_SOC_WM8994 if SND_SOC_I2C_AND_SPI
|
||||
select SND_SOC_WM9081 if I2C
|
||||
select SND_SOC_WM9705 if SND_SOC_AC97_BUS
|
||||
select SND_SOC_WM9712 if SND_SOC_AC97_BUS
|
||||
@@ -205,6 +206,9 @@ config SND_SOC_WM8990
|
||||
config SND_SOC_WM8993
|
||||
tristate
|
||||
|
||||
config SND_SOC_WM8994
|
||||
tristate
|
||||
|
||||
config SND_SOC_WM9081
|
||||
tristate
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ snd-soc-wm8974-objs := wm8974.o
|
||||
snd-soc-wm8988-objs := wm8988.o
|
||||
snd-soc-wm8990-objs := wm8990.o
|
||||
snd-soc-wm8993-objs := wm8993.o
|
||||
snd-soc-wm8994-objs := wm8994.o
|
||||
snd-soc-wm9081-objs := wm9081.o
|
||||
snd-soc-wm9705-objs := wm9705.o
|
||||
snd-soc-wm9712-objs := wm9712.o
|
||||
@@ -89,6 +90,7 @@ obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
|
||||
obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
|
||||
obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
|
||||
obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
|
||||
obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
|
||||
obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
|
||||
obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
|
||||
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
|
||||
|
||||
2691
sound/soc/codecs/wm8994.c
Executable file
2691
sound/soc/codecs/wm8994.c
Executable file
File diff suppressed because it is too large
Load Diff
60
sound/soc/codecs/wm8994.h
Normal file
60
sound/soc/codecs/wm8994.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2005 Openedhand Ltd.
|
||||
*
|
||||
* Author: Richard Purdie <richard@openedhand.com>
|
||||
*
|
||||
* Based on WM8753.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _WM8994_H
|
||||
#define _WM8994_H
|
||||
|
||||
/* WM8994 register space */
|
||||
|
||||
#define WM8994_LINVOL 0x0f
|
||||
#define WM8994_RINVOL 0x01
|
||||
#define WM8994_LOUT1V 0x02
|
||||
#define WM8994_ROUT1V 0x03
|
||||
#define WM8994_ADCDAC 0x05
|
||||
#define WM8994_IFACE 0x07
|
||||
#define WM8994_SRATE 0x08
|
||||
#define WM8994_LDAC 0x0a
|
||||
#define WM8994_RDAC 0x0b
|
||||
#define WM8994_BASS 0x0c
|
||||
#define WM8994_TREBLE 0x0d
|
||||
#define WM8994_RESET 0x00
|
||||
#define WM8994_3D 0x10
|
||||
#define WM8994_ALC1 0x11
|
||||
#define WM8994_ALC2 0x12
|
||||
#define WM8994_ALC3 0x13
|
||||
#define WM8994_NGATE 0x14
|
||||
#define WM8994_LADC 0x15
|
||||
#define WM8994_RADC 0x16
|
||||
#define WM8994_ADCTL1 0x17
|
||||
#define WM8994_ADCTL2 0x18
|
||||
#define WM8994_PWR1 0x19
|
||||
#define WM8994_PWR2 0x1a
|
||||
#define WM8994_ADCTL3 0x1b
|
||||
#define WM8994_ADCIN 0x1f
|
||||
#define WM8994_LADCIN 0x20
|
||||
#define WM8994_RADCIN 0x21
|
||||
#define WM8994_LOUTM1 0x22
|
||||
#define WM8994_LOUTM2 0x23
|
||||
#define WM8994_ROUTM1 0x24
|
||||
#define WM8994_ROUTM2 0x25
|
||||
#define WM8994_LOUT2V 0x28
|
||||
#define WM8994_ROUT2V 0x29
|
||||
#define WM8994_LPPB 0x43
|
||||
#define WM8994_NUM_REG 0x44
|
||||
|
||||
#define WM8994_SYSCLK 0
|
||||
|
||||
extern struct snd_soc_dai wm8994_dai;
|
||||
extern struct snd_soc_codec_device soc_codec_dev_wm8994;
|
||||
|
||||
#endif
|
||||
@@ -39,10 +39,10 @@ config SND_ROCKCHIP_SOC_RK1000
|
||||
if SND_ROCKCHIP_SOC_WM8988 || SND_ROCKCHIP_SOC_RK1000 || SND_ROCKCHIP_SOC_WM8994
|
||||
choice
|
||||
prompt "set i2s type"
|
||||
config SND_ROCKCHIP_SOC_SLAVE
|
||||
tristate "I2s run in slave Mode codec run in Master"
|
||||
config SND_CODEC_SOC_MASTER
|
||||
tristate "Codec run in Master"
|
||||
|
||||
config SND_ROCKCHIP_SOC_MASTER
|
||||
tristate "I2s run in master Mode codec run in Master"
|
||||
config SND_CODEC_SOC_SLAVE
|
||||
tristate "Codec run in Slave"
|
||||
endchoice
|
||||
endif
|
||||
|
||||
186
sound/soc/rk2818/rk2818_wm8994.c
Executable file
186
sound/soc/rk2818/rk2818_wm8994.c
Executable file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* rk2818_wm8988.c -- SoC audio for rockchip
|
||||
*
|
||||
* Driver for rockchip wm8988 audio
|
||||
* Copyright (C) 2009 lhh
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/soc-dapm.h>
|
||||
#include <asm/io.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
#include "../codecs/wm8994.h"
|
||||
#include "rk2818_pcm.h"
|
||||
#include "rk2818_i2s.h"
|
||||
|
||||
#if 0
|
||||
#define DBG(x...) printk(KERN_INFO x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
static int rk2818_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
|
||||
int ret;
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
/*by Vincent Hsiung for EQ Vol Change*/
|
||||
#define HW_PARAMS_FLAG_EQVOL_ON 0x21
|
||||
#define HW_PARAMS_FLAG_EQVOL_OFF 0x22
|
||||
if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF))
|
||||
{
|
||||
ret = codec_dai->ops->hw_params(substream, params, codec_dai); //by Vincent
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set codec DAI configuration */
|
||||
#if defined (CONFIG_SND_ROCKCHIP_SOC_MASTER)
|
||||
ret = codec_dai->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
|
||||
#endif
|
||||
#if defined (CONFIG_SND_ROCKCHIP_SOC_SLAVE)
|
||||
ret = codec_dai->ops->set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM );
|
||||
#endif
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* set cpu DAI configuration */
|
||||
#if defined (CONFIG_SND_ROCKCHIP_SOC_MASTER)
|
||||
ret = cpu_dai->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
|
||||
#endif
|
||||
#if defined (CONFIG_SND_ROCKCHIP_SOC_SLAVE)
|
||||
ret = cpu_dai->ops->set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
|
||||
#endif
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget rk2818_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_LINE("Audio Out", NULL),
|
||||
SND_SOC_DAPM_LINE("Line in", NULL),
|
||||
SND_SOC_DAPM_MIC("Micn", NULL),
|
||||
SND_SOC_DAPM_MIC("Micp", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route audio_map[]= {
|
||||
|
||||
{"Audio Out", NULL, "LOUT1"},
|
||||
{"Audio Out", NULL, "ROUT1"},
|
||||
{"Line in", NULL, "RINPUT1"},
|
||||
{"Line in", NULL, "LINPUT1"},
|
||||
{"Micn", NULL, "RINPUT2"},
|
||||
{"Micp", NULL, "LINPUT2"},
|
||||
};
|
||||
|
||||
/*
|
||||
* Logic for a wm8994 as connected on a rockchip board.
|
||||
*/
|
||||
static int rk2818_wm8994_init(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct snd_soc_dai *codec_dai = &codec->dai[0];
|
||||
int ret;
|
||||
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, 0,
|
||||
12000000, SND_SOC_CLOCK_IN);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "Failed to set WM8994 SYSCLK: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add specific widgets */
|
||||
snd_soc_dapm_new_controls(codec, rk2818_dapm_widgets,
|
||||
ARRAY_SIZE(rk2818_dapm_widgets));
|
||||
snd_soc_dapm_nc_pin(codec, "LOUT2");
|
||||
snd_soc_dapm_nc_pin(codec, "ROUT2");
|
||||
|
||||
/* Set up specific audio path audio_mapnects */
|
||||
snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
|
||||
|
||||
snd_soc_dapm_sync(codec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops rk2818_ops = {
|
||||
.hw_params = rk2818_hw_params,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_link rk2818_dai = {
|
||||
.name = "WM8994",
|
||||
.stream_name = "WM8994 PCM",
|
||||
.cpu_dai = &rk2818_i2s_dai,
|
||||
.codec_dai = &wm8994_dai,
|
||||
.init = rk2818_wm8994_init,
|
||||
.ops = &rk2818_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_card_rk2818 = {
|
||||
.name = "RK2818_WM8994",
|
||||
.platform = &rk2818_soc_platform,
|
||||
.dai_link = &rk2818_dai,
|
||||
.num_links = 1,
|
||||
};
|
||||
|
||||
|
||||
static struct snd_soc_device rk2818_snd_devdata = {
|
||||
.card = &snd_soc_card_rk2818,
|
||||
.codec_dev = &soc_codec_dev_wm8994,
|
||||
};
|
||||
|
||||
static struct platform_device *rk2818_snd_device;
|
||||
|
||||
static int __init audio_card_init(void)
|
||||
{
|
||||
int ret =0;
|
||||
DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
rk2818_snd_device = platform_device_alloc("soc-audio", -1);
|
||||
if (!rk2818_snd_device) {
|
||||
DBG("platform device allocation failed\n");
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
platform_set_drvdata(rk2818_snd_device, &rk2818_snd_devdata);
|
||||
rk2818_snd_devdata.dev = &rk2818_snd_device->dev;
|
||||
ret = platform_device_add(rk2818_snd_device);
|
||||
if (ret) {
|
||||
DBG("platform device add failed\n");
|
||||
platform_device_put(rk2818_snd_device);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static void __exit audio_card_exit(void)
|
||||
{
|
||||
platform_device_unregister(rk2818_snd_device);
|
||||
}
|
||||
|
||||
module_init(audio_card_init);
|
||||
module_exit(audio_card_exit);
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("lhh lhh@rock-chips.com");
|
||||
MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface");
|
||||
MODULE_LICENSE("GPL");
|
||||
Reference in New Issue
Block a user