audio : enable tpa2028d
Change-Id: Id35a8bf66b1b730d32d1d8cbc68cd3d7f607e72e
This commit is contained in:
committed by
Iliyan Malchev
parent
922e87a2a4
commit
45717e0a26
@@ -353,6 +353,7 @@ CONFIG_SND_USB_AUDIO=y
|
|||||||
CONFIG_SND_SOC=y
|
CONFIG_SND_SOC=y
|
||||||
CONFIG_SND_SOC_MSM8960=y
|
CONFIG_SND_SOC_MSM8960=y
|
||||||
CONFIG_SND_SOC_DUAL_AMIC=y
|
CONFIG_SND_SOC_DUAL_AMIC=y
|
||||||
|
CONFIG_SND_SOC_TPA2028D=y
|
||||||
CONFIG_HID_APPLE=y
|
CONFIG_HID_APPLE=y
|
||||||
CONFIG_HID_MAGICMOUSE=y
|
CONFIG_HID_MAGICMOUSE=y
|
||||||
CONFIG_HID_MICROSOFT=y
|
CONFIG_HID_MICROSOFT=y
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include "../../../../sound/soc/codecs/wcd9310.h"
|
#include "../../../../sound/soc/codecs/wcd9310.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_LGE_AUDIO_TPA2028D
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
#include <sound/tpa2028d.h>
|
#include <sound/tpa2028d.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -77,12 +77,7 @@ struct fsa8008_platform_data {
|
|||||||
unsigned int latency_for_detection;
|
unsigned int latency_for_detection;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_LGE_AUDIO_TPA2028D
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
int amp_power(bool on)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int amp_enable(int on_state)
|
int amp_enable(int on_state)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
@@ -135,7 +130,6 @@ int amp_enable(int on_state)
|
|||||||
|
|
||||||
static struct audio_amp_platform_data amp_platform_data = {
|
static struct audio_amp_platform_data amp_platform_data = {
|
||||||
.enable = amp_enable,
|
.enable = amp_enable,
|
||||||
.power = amp_power,
|
|
||||||
.agc_compression_rate = AGC_COMPRESIION_RATE,
|
.agc_compression_rate = AGC_COMPRESIION_RATE,
|
||||||
.agc_output_limiter_disable = AGC_OUTPUT_LIMITER_DISABLE,
|
.agc_output_limiter_disable = AGC_OUTPUT_LIMITER_DISABLE,
|
||||||
.agc_fixed_gain = AGC_FIXED_GAIN,
|
.agc_fixed_gain = AGC_FIXED_GAIN,
|
||||||
@@ -143,7 +137,7 @@ static struct audio_amp_platform_data amp_platform_data = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct i2c_board_info msm_i2c_audiosubsystem_info[] = {
|
static struct i2c_board_info msm_i2c_audiosubsystem_info[] = {
|
||||||
#ifdef CONFIG_LGE_AUDIO_TPA2028D
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
{
|
{
|
||||||
I2C_BOARD_INFO("tpa2028d_amp", TPA2028D_ADDRESS),
|
I2C_BOARD_INFO("tpa2028d_amp", TPA2028D_ADDRESS),
|
||||||
.platform_data = &_platform_data,
|
.platform_data = &_platform_data,
|
||||||
|
|||||||
50
include/sound/tpa2028d.h
Normal file
50
include/sound/tpa2028d.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/* include/sound/tpa2028d.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 LGE, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Revision 0.1 -- BJB -- 3/18/10 -- Original Version
|
||||||
|
* Revision 0.2 -- BJB -- 3/19/10 -- Corrected dB to DB in Register 0x01, Added function prototypes.
|
||||||
|
* Revision 0.3 -- AME -- 5/17/10 -- No changes to TPA2055D3_FDK.h file.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ---- I2C ADDR -----*/
|
||||||
|
#define IC_CONTROL (char) 0x01
|
||||||
|
#define AGC_ATTACK_CONTROL (char) 0x02
|
||||||
|
#define AGC_RELEASE_CONTROL (char) 0x03
|
||||||
|
#define AGC_HOLD_TIME_CONTROL (char) 0x04
|
||||||
|
#define AGC_FIXED_GAIN_CONTROL (char) 0x05
|
||||||
|
#define AGC1_CONTROL (char) 0x06
|
||||||
|
#define AGC2_CONTROL (char) 0x07
|
||||||
|
|
||||||
|
struct amp_cal {
|
||||||
|
u8 dev_type;
|
||||||
|
u8 gain_type;
|
||||||
|
u8 data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void set_amp_gain(int num);
|
||||||
|
|
||||||
|
struct audio_amp_platform_data {
|
||||||
|
int (*enable)(int);
|
||||||
|
int (*power)(bool);
|
||||||
|
char agc_compression_rate;
|
||||||
|
char agc_output_limiter_disable;
|
||||||
|
char agc_fixed_gain;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SPK FUNCTION */
|
||||||
|
#define SPK_ON 1
|
||||||
|
#define SPK_OFF 0
|
||||||
@@ -448,3 +448,9 @@ config SND_SOC_TPA6130A2
|
|||||||
|
|
||||||
config SND_SOC_MSM_STUB
|
config SND_SOC_MSM_STUB
|
||||||
tristate
|
tristate
|
||||||
|
|
||||||
|
config SND_SOC_TPA2028D
|
||||||
|
bool "Audio subsystem TPA2028D"
|
||||||
|
default y
|
||||||
|
---help---
|
||||||
|
Texas Instruments 3W Mono Class-D Audio Amplifier
|
||||||
|
|||||||
@@ -212,3 +212,4 @@ obj-$(CONFIG_SND_SOC_MSM_STUB) += snd-soc-msm-stub.o
|
|||||||
# Amp
|
# Amp
|
||||||
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
|
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
|
||||||
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
|
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
|
||||||
|
obj-$(CONFIG_SND_SOC_TPA2028D) += tpa2028d.o
|
||||||
|
|||||||
321
sound/soc/codecs/tpa2028d.c
Normal file
321
sound/soc/codecs/tpa2028d.c
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
/* sound/soc/codecs/tpa2028d.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 LGE, 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
#include <linux/jiffies.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/miscdevice.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <asm/ioctls.h>
|
||||||
|
#include <mach/debug_mm.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include <sound/tpa2028d.h>
|
||||||
|
|
||||||
|
#define MODULE_NAME "tpa2028d"
|
||||||
|
|
||||||
|
#undef AMP_DEBUG_PRINT
|
||||||
|
#define AMP_DEBUG_PRINT
|
||||||
|
|
||||||
|
#define AMP_IOCTL_MAGIC 't'
|
||||||
|
#define AMP_SET_DATA _IOW(AMP_IOCTL_MAGIC, 0, struct amp_cal *)
|
||||||
|
#define AMP_GET_DATA _IOW(AMP_IOCTL_MAGIC, 1, struct amp_cal *)
|
||||||
|
|
||||||
|
static uint32_t msm_snd_debug = 1;
|
||||||
|
module_param_named(debug_mask, msm_snd_debug, uint, 0664);
|
||||||
|
|
||||||
|
#if defined (AMP_DEBUG_PRINT)
|
||||||
|
#define D(fmt, args...) printk(KERN_INFO "[%s:%5d]" fmt, __func__, __LINE__, ##args)
|
||||||
|
#else
|
||||||
|
#define D(fmt, args...) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct amp_config {
|
||||||
|
struct i2c_client *client;
|
||||||
|
struct audio_amp_platform_data *pdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct amp_config *amp_data = NULL;
|
||||||
|
|
||||||
|
int ReadI2C(char reg, char *ret)
|
||||||
|
{
|
||||||
|
|
||||||
|
unsigned int err;
|
||||||
|
unsigned char buf = reg;
|
||||||
|
|
||||||
|
struct i2c_msg msg[2] = {
|
||||||
|
{ amp_data->client->addr, 0, 1, &buf },
|
||||||
|
{ amp_data->client->addr, I2C_M_RD, 1, ret}
|
||||||
|
};
|
||||||
|
err = i2c_transfer(amp_data->client->adapter, msg, 2);
|
||||||
|
if (err < 0)
|
||||||
|
D("i2c read error:%x\n", reg);
|
||||||
|
else
|
||||||
|
D("i2c read ok:%x\n", reg);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int WriteI2C(char reg, char val)
|
||||||
|
{
|
||||||
|
|
||||||
|
int err;
|
||||||
|
unsigned char buf[2];
|
||||||
|
struct i2c_msg msg = {amp_data->client->addr, 0, 2, buf };
|
||||||
|
|
||||||
|
buf[0] = reg;
|
||||||
|
buf[1] = val;
|
||||||
|
err = i2c_transfer(amp_data->client->adapter, &msg, 1);
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
D("i2c write error:%x:%x\n", reg, val);
|
||||||
|
return -EIO;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tpa2028d_poweron(void)
|
||||||
|
{
|
||||||
|
int fail = 0;
|
||||||
|
char agc_compression_rate = amp_data->pdata->agc_compression_rate;
|
||||||
|
char agc_output_limiter_disable = amp_data->pdata->agc_output_limiter_disable;
|
||||||
|
char agc_fixed_gain = amp_data->pdata->agc_fixed_gain;
|
||||||
|
|
||||||
|
agc_output_limiter_disable = (agc_output_limiter_disable<<7);
|
||||||
|
|
||||||
|
fail |= WriteI2C(IC_CONTROL, 0xE3); /*Tuen On*/
|
||||||
|
fail |= WriteI2C(AGC_ATTACK_CONTROL, 0x05); /*Tuen On*/
|
||||||
|
fail |= WriteI2C(AGC_RELEASE_CONTROL, 0x0B); /*Tuen On*/
|
||||||
|
fail |= WriteI2C(AGC_HOLD_TIME_CONTROL, 0x00); /*Tuen On*/
|
||||||
|
fail |= WriteI2C(AGC_FIXED_GAIN_CONTROL, agc_fixed_gain); /*Tuen On*/
|
||||||
|
fail |= WriteI2C(AGC1_CONTROL, 0x3A|agc_output_limiter_disable); /*Tuen On*/
|
||||||
|
fail |= WriteI2C(AGC2_CONTROL, 0xC0|agc_compression_rate); /*Tuen On*/
|
||||||
|
fail |= WriteI2C(IC_CONTROL, 0xC3); /*Tuen On*/
|
||||||
|
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tpa2028d_powerdown(void)
|
||||||
|
{
|
||||||
|
int fail = 0;
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void set_amp_gain(int amp_state)
|
||||||
|
{
|
||||||
|
int fail = 0;
|
||||||
|
|
||||||
|
switch (amp_state) {
|
||||||
|
case SPK_ON:
|
||||||
|
/* if the delay time is need for chip ready,
|
||||||
|
* should be added to each power or enable function.
|
||||||
|
*/
|
||||||
|
if (amp_data->pdata->power)
|
||||||
|
fail = amp_data->pdata->power(1);
|
||||||
|
/*need 5 msec for prevent mute issue*/
|
||||||
|
msleep(5);
|
||||||
|
if (amp_data->pdata->enable)
|
||||||
|
fail = amp_data->pdata->enable(1);
|
||||||
|
/*need 10 msec for chip ready*/
|
||||||
|
msleep(10);
|
||||||
|
fail = tpa2028d_poweron();
|
||||||
|
break;
|
||||||
|
case SPK_OFF:
|
||||||
|
if (amp_data->pdata->enable)
|
||||||
|
fail = amp_data->pdata->enable(2);
|
||||||
|
fail = tpa2028d_powerdown();
|
||||||
|
if (amp_data->pdata->enable)
|
||||||
|
fail = amp_data->pdata->enable(0);
|
||||||
|
if (amp_data->pdata->power)
|
||||||
|
fail = amp_data->pdata->power(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
D("Amp_state [%d] does not support \n", amp_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(set_amp_gain);
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
tpa2028d_comp_rate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct audio_amp_platform_data *pdata = amp_data->pdata;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
if (sscanf(buf, "%d", &val) != 1)
|
||||||
|
return -EINVAL;
|
||||||
|
if (val > 3 || val < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pdata->agc_compression_rate = val;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
tpa2028d_comp_rate_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct audio_amp_platform_data *pdata = amp_data->pdata;
|
||||||
|
char val = 0;
|
||||||
|
|
||||||
|
ReadI2C(AGC2_CONTROL, &val);
|
||||||
|
|
||||||
|
D("[tpa2028d_comp_rate_show] val : %x \n",val);
|
||||||
|
|
||||||
|
return sprintf(buf, "AGC2_CONTROL : %x, pdata->agc_compression_rate : %d\n", val, pdata->agc_compression_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
tpa2028d_out_lim_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct audio_amp_platform_data *pdata = amp_data->pdata;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
if (sscanf(buf, "%d", &val) != 1)
|
||||||
|
return -EINVAL;
|
||||||
|
pdata->agc_output_limiter_disable = val&0x0001;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
tpa2028d_out_lim_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct audio_amp_platform_data *pdata = amp_data->pdata;
|
||||||
|
char val=0;
|
||||||
|
|
||||||
|
ReadI2C(AGC1_CONTROL, &val);
|
||||||
|
|
||||||
|
D("[tpa2028d_out_lim_show] val : %x \n",val);
|
||||||
|
|
||||||
|
return sprintf(buf, "AGC1_CONTROL : %x, pdata->agc_output_limiter_disable : %d\n", val, pdata->agc_output_limiter_disable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
tpa2028d_fixed_gain_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct audio_amp_platform_data *pdata = amp_data->pdata;
|
||||||
|
int val;
|
||||||
|
|
||||||
|
if (sscanf(buf, "%d", &val) != 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pdata->agc_fixed_gain = val;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
tpa2028d_fixed_gain_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct audio_amp_platform_data *pdata = amp_data->pdata;
|
||||||
|
char val=0;
|
||||||
|
|
||||||
|
ReadI2C(AGC_FIXED_GAIN_CONTROL, &val);
|
||||||
|
|
||||||
|
D("[tpa2028d_fixed_gain_show] val : %x \n",val);
|
||||||
|
|
||||||
|
return sprintf(buf, "fixed_gain : %x, pdata->agc_fixed_gain : %d\n", val, pdata->agc_fixed_gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct device_attribute tpa2028d_device_attrs[] = {
|
||||||
|
__ATTR(comp_rate, S_IRUGO | S_IWUSR, tpa2028d_comp_rate_show, tpa2028d_comp_rate_store),
|
||||||
|
__ATTR(out_lim, S_IRUGO | S_IWUSR, tpa2028d_out_lim_show, tpa2028d_out_lim_store),
|
||||||
|
__ATTR(fixed_gain, S_IRUGO | S_IWUSR, tpa2028d_fixed_gain_show, tpa2028d_fixed_gain_store),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tpa2028d_amp_probe(struct i2c_client *client,
|
||||||
|
const struct i2c_device_id *id)
|
||||||
|
{
|
||||||
|
struct amp_config *data;
|
||||||
|
struct audio_amp_platform_data *pdata;
|
||||||
|
struct i2c_adapter *adapter = client->adapter;
|
||||||
|
int err, i;
|
||||||
|
|
||||||
|
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
|
||||||
|
err = -EOPNOTSUPP;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdata = client->dev.platform_data;
|
||||||
|
if (pdata == NULL) {
|
||||||
|
D("platform data is null\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = kzalloc(sizeof(struct amp_config), GFP_KERNEL);
|
||||||
|
if (data == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
amp_data = data;
|
||||||
|
amp_data->pdata = pdata;
|
||||||
|
data->client = client;
|
||||||
|
i2c_set_clientdata(client, data);
|
||||||
|
|
||||||
|
set_amp_gain(SPK_OFF);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(tpa2028d_device_attrs); i++) {
|
||||||
|
err = device_create_file(&client->dev, &tpa2028d_device_attrs[i]);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tpa2028d_amp_remove(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
struct amp_config *data = i2c_get_clientdata(client);
|
||||||
|
kfree(data);
|
||||||
|
|
||||||
|
i2c_set_clientdata(client, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct i2c_device_id tpa2028d_amp_idtable[] = {
|
||||||
|
{ "tpa2028d_amp", 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_driver tpa2028d_amp_driver = {
|
||||||
|
.probe = tpa2028d_amp_probe,
|
||||||
|
.remove = tpa2028d_amp_remove,
|
||||||
|
.id_table = tpa2028d_amp_idtable,
|
||||||
|
.driver = {
|
||||||
|
.name = MODULE_NAME,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int __init tpa2028d_amp_init(void)
|
||||||
|
{
|
||||||
|
return i2c_add_driver(&tpa2028d_amp_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit tpa2028d_amp_exit(void)
|
||||||
|
{
|
||||||
|
return i2c_del_driver(&tpa2028d_amp_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(tpa2028d_amp_init);
|
||||||
|
module_exit(tpa2028d_amp_exit);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("TPA2028D Amp Control");
|
||||||
|
MODULE_AUTHOR("Kim EunHye <ehgrace.kim@lge.com>");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
@@ -30,6 +30,10 @@
|
|||||||
#include "msm-pcm-routing.h"
|
#include "msm-pcm-routing.h"
|
||||||
#include "../codecs/wcd9310.h"
|
#include "../codecs/wcd9310.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
|
#include <sound/tpa2028d.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 8064 machine driver */
|
/* 8064 machine driver */
|
||||||
|
|
||||||
#define PM8921_GPIO_BASE NR_GPIO_IRQS
|
#define PM8921_GPIO_BASE NR_GPIO_IRQS
|
||||||
@@ -226,10 +230,14 @@ static void msm_ext_spk_power_amp_on(u32 spk)
|
|||||||
(msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) ||
|
(msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) ||
|
||||||
(msm_ext_top_spk_pamp & TOP_SPK_AMP)) {
|
(msm_ext_top_spk_pamp & TOP_SPK_AMP)) {
|
||||||
|
|
||||||
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
|
set_amp_gain(SPK_ON);
|
||||||
|
#else
|
||||||
msm_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
|
msm_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
|
||||||
pr_debug("%s: sleeping 4 ms after turning on "
|
pr_debug("%s: sleeping 4 ms after turning on "
|
||||||
" external Top Speaker Ampl\n", __func__);
|
" external Top Speaker Ampl\n", __func__);
|
||||||
usleep_range(4000, 4000);
|
usleep_range(4000, 4000);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -274,6 +282,10 @@ static void msm_ext_spk_power_amp_off(u32 spk)
|
|||||||
if (msm_ext_top_spk_pamp)
|
if (msm_ext_top_spk_pamp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
|
set_amp_gain(SPK_OFF);
|
||||||
|
msm_ext_top_spk_pamp = 0;
|
||||||
|
#else
|
||||||
gpio_direction_output(top_spk_pamp_gpio, 0);
|
gpio_direction_output(top_spk_pamp_gpio, 0);
|
||||||
gpio_free(top_spk_pamp_gpio);
|
gpio_free(top_spk_pamp_gpio);
|
||||||
msm_ext_top_spk_pamp = 0;
|
msm_ext_top_spk_pamp = 0;
|
||||||
@@ -282,6 +294,7 @@ static void msm_ext_spk_power_amp_off(u32 spk)
|
|||||||
__func__);
|
__func__);
|
||||||
|
|
||||||
usleep_range(4000, 4000);
|
usleep_range(4000, 4000);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
|
pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
|
||||||
@@ -300,11 +313,17 @@ static void msm_ext_control(struct snd_soc_codec *codec)
|
|||||||
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
|
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
|
||||||
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
|
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
|
||||||
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
|
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
|
||||||
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
|
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top");
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos");
|
snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos");
|
||||||
snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg");
|
snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg");
|
||||||
snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos");
|
snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos");
|
||||||
snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg");
|
snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg");
|
||||||
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
|
snd_soc_dapm_disable_pin(dapm, "Ext Spk Top");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_soc_dapm_sync(dapm);
|
snd_soc_dapm_sync(dapm);
|
||||||
@@ -504,13 +523,16 @@ static const struct snd_soc_dapm_route apq8064_common_audio_map[] = {
|
|||||||
{"HEADPHONE", NULL, "LDO_H"},
|
{"HEADPHONE", NULL, "LDO_H"},
|
||||||
|
|
||||||
/* Speaker path */
|
/* Speaker path */
|
||||||
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
|
{"Ext Spk Top", NULL, "LINEOUT1"},
|
||||||
|
#else
|
||||||
{"Ext Spk Bottom Pos", NULL, "LINEOUT1"},
|
{"Ext Spk Bottom Pos", NULL, "LINEOUT1"},
|
||||||
{"Ext Spk Bottom Neg", NULL, "LINEOUT3"},
|
{"Ext Spk Bottom Neg", NULL, "LINEOUT3"},
|
||||||
|
|
||||||
{"Ext Spk Top Pos", NULL, "LINEOUT2"},
|
{"Ext Spk Top Pos", NULL, "LINEOUT2"},
|
||||||
{"Ext Spk Top Neg", NULL, "LINEOUT4"},
|
{"Ext Spk Top Neg", NULL, "LINEOUT4"},
|
||||||
{"Ext Spk Top", NULL, "LINEOUT5"},
|
{"Ext Spk Top", NULL, "LINEOUT5"},
|
||||||
|
#endif
|
||||||
/************ Analog MIC Paths ************/
|
/************ Analog MIC Paths ************/
|
||||||
#ifdef CONFIG_SND_SOC_DUAL_AMIC
|
#ifdef CONFIG_SND_SOC_DUAL_AMIC
|
||||||
/* Handset Mic */
|
/* Handset Mic */
|
||||||
@@ -1158,10 +1180,14 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
ARRAY_SIZE(apq8064_liquid_cdp_audio_map));
|
ARRAY_SIZE(apq8064_liquid_cdp_audio_map));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SND_SOC_TPA2028D
|
||||||
|
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top");
|
||||||
|
#else
|
||||||
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
|
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
|
||||||
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
|
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
|
||||||
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
|
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
|
||||||
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
|
snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
|
||||||
|
#endif
|
||||||
|
|
||||||
snd_soc_dapm_sync(dapm);
|
snd_soc_dapm_sync(dapm);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user