ASoC: msm: critical tasha fixes
tasha fixes pulled in by the below change id. I4ca4a554c0a83d4053301ca5dd2afb8b09fa5194 I2cb4447b36fef111ed1f9b8991b3882b8d57f6a7 I80ee0dedac8fa81ce54a0e61c839a97b9b45d36b Change-Id: I258d5bb48a25f13e0c0f348a8f6a7bf1b38922d0 Signed-off-by: Santosh Mardi <gsantosh@codeaurora.org>
This commit is contained in:
parent
3d9b219cf4
commit
6203e5d262
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -476,6 +476,15 @@ int swr_bulk_write(struct swr_device *dev, u8 dev_num, void *reg,
|
|||
return -EINVAL;
|
||||
|
||||
master = dev->master;
|
||||
if (dev->group_id) {
|
||||
if (master->gr_sid != dev_num) {
|
||||
if (!master->gr_sid)
|
||||
master->gr_sid = dev_num;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
dev_num = dev->group_id;
|
||||
}
|
||||
if (master->bulk_write)
|
||||
return master->bulk_write(master, dev_num, reg, buf, len);
|
||||
|
||||
|
@ -499,6 +508,16 @@ int swr_write(struct swr_device *dev, u8 dev_num, u16 reg_addr,
|
|||
struct swr_master *master = dev->master;
|
||||
if (!master)
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->group_id) {
|
||||
if (master->gr_sid != dev_num) {
|
||||
if (!master->gr_sid)
|
||||
master->gr_sid = dev_num;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
dev_num = dev->group_id;
|
||||
}
|
||||
return master->write(master, dev_num, reg_addr, buf);
|
||||
}
|
||||
EXPORT_SYMBOL(swr_write);
|
||||
|
@ -588,6 +607,31 @@ int swr_reset_device(struct swr_device *swr_dev)
|
|||
}
|
||||
EXPORT_SYMBOL(swr_reset_device);
|
||||
|
||||
/**
|
||||
* swr_set_device_group - Assign group id to the slave devices
|
||||
* @swr_dev: pointer to soundwire slave device
|
||||
* @id: group id to be assigned to slave device
|
||||
* Context: can sleep
|
||||
*
|
||||
* This API will be called either from soundwire master or slave
|
||||
* device to assign group id.
|
||||
*/
|
||||
int swr_set_device_group(struct swr_device *swr_dev, u8 id)
|
||||
{
|
||||
struct swr_master *master;
|
||||
|
||||
if (!swr_dev)
|
||||
return -EINVAL;
|
||||
|
||||
swr_dev->group_id = id;
|
||||
master = swr_dev->master;
|
||||
if (!id && master)
|
||||
master->gr_sid = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(swr_set_device_group);
|
||||
|
||||
static int swr_drv_probe(struct device *dev)
|
||||
{
|
||||
const struct swr_driver *sdrv = to_swr_driver(dev->driver);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -30,7 +30,7 @@
|
|||
#include "swr-wcd-ctrl.h"
|
||||
|
||||
#define SWR_BROADCAST_CMD_ID 0x0F
|
||||
#define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */
|
||||
#define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */
|
||||
#define SWR_DEV_ID_MASK 0xFFFFFFFF
|
||||
#define SWR_REG_VAL_PACK(data, dev, id, reg) \
|
||||
((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24))
|
||||
|
@ -162,7 +162,7 @@ enum {
|
|||
|
||||
#define SWR_MSTR_MAX_REG_ADDR 0x1740
|
||||
#define SWR_MSTR_START_REG_ADDR 0x00
|
||||
#define SWR_MSTR_MAX_BUF_LEN 20
|
||||
#define SWR_MSTR_MAX_BUF_LEN 32
|
||||
#define BYTES_PER_LINE 12
|
||||
#define SWR_MSTR_RD_BUF_LEN 8
|
||||
#define SWR_MSTR_WR_BUF_LEN 32
|
||||
|
@ -391,6 +391,7 @@ static int swrm_get_port_config(struct swr_master *master)
|
|||
static int swrm_get_master_port(u8 *mstr_port_id, u8 slv_port_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
|
||||
if (mstr_ports[i] == slv_port_id) {
|
||||
*mstr_port_id = i;
|
||||
|
@ -480,6 +481,7 @@ static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr,
|
|||
dev_err(&master->dev, "%s: swrm is NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dev_num)
|
||||
ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr,
|
||||
len);
|
||||
|
@ -503,10 +505,12 @@ static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr,
|
|||
dev_err(&master->dev, "%s: swrm is NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dev_num)
|
||||
ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr);
|
||||
else
|
||||
ret = swrm->write(swrm->handle, reg_addr, reg_val);
|
||||
|
||||
pm_runtime_mark_last_busy(&swrm->pdev->dev);
|
||||
|
||||
return ret;
|
||||
|
@ -612,7 +616,14 @@ static void swrm_apply_port_config(struct swr_master *master)
|
|||
int len = 0;
|
||||
|
||||
int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK |
|
||||
SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK);
|
||||
SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK |
|
||||
SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK);
|
||||
|
||||
if (!swrm) {
|
||||
pr_err("%s: Invalid handle to swr controller\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
bank = get_inactive_bank_num(swrm);
|
||||
dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n",
|
||||
|
@ -622,7 +633,8 @@ static void swrm_apply_port_config(struct swr_master *master)
|
|||
value = swrm->read(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
|
||||
value &= (~mask);
|
||||
value |= ((0 << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
|
||||
(7 << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT));
|
||||
(7 << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
|
||||
(0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
|
||||
swrm->write(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
|
||||
dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__,
|
||||
SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
|
||||
|
@ -707,9 +719,10 @@ static int swrm_connect_port(struct swr_master *master,
|
|||
if (!portinfo)
|
||||
return -EINVAL;
|
||||
|
||||
if (swrm == NULL) {
|
||||
dev_err(&master->dev, "%s: invalid soundwire master pointer",
|
||||
__func__);
|
||||
if (!swrm) {
|
||||
dev_err(&master->dev,
|
||||
"%s: Invalid handle to swr controller\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -750,7 +763,13 @@ static int swrm_connect_port(struct swr_master *master,
|
|||
|
||||
swrm_get_port_config(master);
|
||||
swr_port_response(master, portinfo->tid);
|
||||
swrm_apply_port_config(master);
|
||||
if (swrm->num_rx_chs > 1) {
|
||||
swrm->num_cfg_devs += 1;
|
||||
if (swrm->num_rx_chs == swrm->num_cfg_devs)
|
||||
swrm_apply_port_config(master);
|
||||
} else {
|
||||
swrm_apply_port_config(master);
|
||||
}
|
||||
mutex_unlock(&swrm->mlock);
|
||||
return 0;
|
||||
|
||||
|
@ -777,6 +796,13 @@ static int swrm_disconnect_port(struct swr_master *master,
|
|||
u32 val[SWRM_MAX_PORT_REG];
|
||||
int len = 0;
|
||||
|
||||
if (!swrm) {
|
||||
dev_err(&master->dev,
|
||||
"%s: Invalid handle to swr controller\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!portinfo) {
|
||||
dev_err(&master->dev, "%s: portinfo is NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
|
@ -831,6 +857,8 @@ static int swrm_disconnect_port(struct swr_master *master,
|
|||
|
||||
master->num_port -= portinfo->num_port;
|
||||
swr_port_response(master, portinfo->tid);
|
||||
if (swrm->num_rx_chs > 1)
|
||||
swrm->num_cfg_devs -= 1;
|
||||
mutex_unlock(&swrm->mlock);
|
||||
|
||||
dev_dbg(&master->dev, "%s: master active ports: %d\n",
|
||||
|
@ -919,7 +947,7 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev)
|
|||
}
|
||||
break;
|
||||
case SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET:
|
||||
dev_err(swrm->dev, "SWR bus clash detected\n");
|
||||
dev_err_ratelimited(swrm->dev, "SWR bus clash detected\n");
|
||||
break;
|
||||
case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW:
|
||||
dev_dbg(swrm->dev, "SWR read FIFO overflow\n");
|
||||
|
@ -932,9 +960,9 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev)
|
|||
break;
|
||||
case SWRM_INTERRUPT_STATUS_CMD_ERROR:
|
||||
value = swrm->read(swrm->handle, SWRM_CMD_FIFO_STATUS);
|
||||
dev_err(swrm->dev,
|
||||
"SWR CMD error, CMD fifo status 0x%x, flushing fifo\n",
|
||||
value);
|
||||
dev_err_ratelimited(swrm->dev,
|
||||
"SWR CMD error, fifo status 0x%x, flushing fifo\n",
|
||||
value);
|
||||
swrm->write(swrm->handle, SWRM_CMD_FIFO_CMD, 0x1);
|
||||
break;
|
||||
case SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION:
|
||||
|
@ -959,7 +987,7 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev)
|
|||
case SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED:
|
||||
break;
|
||||
default:
|
||||
dev_err(swrm->dev, "SWR unkown interrupt\n");
|
||||
dev_err_ratelimited(swrm->dev, "SWR unknown interrupt\n");
|
||||
ret = IRQ_NONE;
|
||||
break;
|
||||
}
|
||||
|
@ -987,15 +1015,19 @@ static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id,
|
|||
int ret = -EINVAL;
|
||||
struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr);
|
||||
|
||||
if (!swrm) {
|
||||
pr_err("%s: Invalid handle to swr controller\n",
|
||||
__func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pm_runtime_get_sync(&swrm->pdev->dev);
|
||||
for (i = 1; i < (mstr->num_dev + 1); i++) {
|
||||
id = ((u64)(swrm->read(swrm->handle,
|
||||
SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32);
|
||||
id |= swrm->read(swrm->handle,
|
||||
SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i));
|
||||
id = id & SWR_DEV_ID_MASK;
|
||||
|
||||
if (id == dev_id) {
|
||||
if ((id & SWR_DEV_ID_MASK) == dev_id) {
|
||||
if (swrm_get_device_status(swrm, i) == 0x01) {
|
||||
*dev_num = i;
|
||||
ret = 0;
|
||||
|
@ -1019,6 +1051,7 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
|
|||
u32 val;
|
||||
u8 row_ctrl = SWR_MAX_ROW;
|
||||
u8 col_ctrl = SWR_MIN_COL;
|
||||
u8 ssp_period = 1;
|
||||
u8 retry_cmd_num = 3;
|
||||
u32 reg[SWRM_MAX_INIT_REG];
|
||||
u32 value[SWRM_MAX_INIT_REG];
|
||||
|
@ -1026,7 +1059,8 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
|
|||
|
||||
/* Clear Rows and Cols */
|
||||
val = ((row_ctrl << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
|
||||
(col_ctrl << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT));
|
||||
(col_ctrl << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
|
||||
(ssp_period << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
|
||||
|
||||
reg[len] = SWRM_MCP_FRAME_CTRL_BANK_ADDR(0);
|
||||
value[len++] = val;
|
||||
|
@ -1055,11 +1089,12 @@ static int swrm_master_init(struct swr_mstr_ctrl *swrm)
|
|||
reg[len] = SWRM_COMP_CFG_ADDR;
|
||||
value[len++] = 0x02;
|
||||
|
||||
reg[len] = SWRM_MCP_BUS_CTRL_ADDR;
|
||||
value[len++] = 0x02;
|
||||
|
||||
reg[len] = SWRM_COMP_CFG_ADDR;
|
||||
value[len++] = 0x03;
|
||||
|
||||
reg[len] = SWRM_INTERRUPT_CLEAR;
|
||||
value[len++] = 0x08;
|
||||
|
||||
swrm->bulk_write(swrm->handle, reg, value, len);
|
||||
|
||||
return ret;
|
||||
|
@ -1146,6 +1181,7 @@ static int swrm_probe(struct platform_device *pdev)
|
|||
swrm->rcmd_id = 0;
|
||||
swrm->wcmd_id = 0;
|
||||
swrm->slave_status = 0;
|
||||
swrm->num_rx_chs = 0;
|
||||
swrm->state = SWR_MSTR_RESUME;
|
||||
init_completion(&swrm->reset);
|
||||
init_completion(&swrm->broadcast);
|
||||
|
@ -1241,6 +1277,7 @@ static int swrm_remove(struct platform_device *pdev)
|
|||
pm_runtime_set_suspended(&pdev->dev);
|
||||
swr_unregister_master(&swrm->master);
|
||||
mutex_destroy(&swrm->mlock);
|
||||
mutex_destroy(&swrm->reslock);
|
||||
kfree(swrm);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1335,12 +1372,13 @@ exit:
|
|||
|
||||
static int swrm_runtime_idle(struct device *dev)
|
||||
{
|
||||
if (pm_runtime_autosuspend_expiration(dev)) {
|
||||
if (pm_runtime_autosuspend_expiration(dev)) {
|
||||
pm_runtime_autosuspend(dev);
|
||||
return -EAGAIN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM_RUNTIME */
|
||||
|
||||
static int swrm_device_down(struct device *dev)
|
||||
|
@ -1420,12 +1458,16 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
|
|||
case SWR_DEVICE_UP:
|
||||
dev_dbg(swrm->dev, "%s: swr master up called\n", __func__);
|
||||
mutex_lock(&swrm->mlock);
|
||||
mutex_lock(&swrm->reslock);
|
||||
if ((swrm->state == SWR_MSTR_RESUME) ||
|
||||
(swrm->state == SWR_MSTR_UP)) {
|
||||
dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n",
|
||||
__func__, swrm->state);
|
||||
} else {
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
mutex_unlock(&swrm->reslock);
|
||||
pm_runtime_get_sync(&pdev->dev);
|
||||
mutex_lock(&swrm->reslock);
|
||||
list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
|
||||
ret = swr_reset_device(swr_dev);
|
||||
if (ret) {
|
||||
|
@ -1438,8 +1480,40 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
|
|||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
}
|
||||
mutex_unlock(&swrm->reslock);
|
||||
mutex_unlock(&swrm->mlock);
|
||||
break;
|
||||
case SWR_SET_NUM_RX_CH:
|
||||
if (!data) {
|
||||
dev_err(swrm->dev, "%s: data is NULL\n", __func__);
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
mutex_lock(&swrm->mlock);
|
||||
swrm->num_rx_chs = *(int *)data;
|
||||
if (swrm->num_rx_chs > 1) {
|
||||
list_for_each_entry(swr_dev, &mstr->devices,
|
||||
dev_list) {
|
||||
ret = swr_set_device_group(swr_dev,
|
||||
SWR_BROADCAST);
|
||||
if (ret)
|
||||
dev_err(swrm->dev,
|
||||
"%s: set num ch failed\n",
|
||||
__func__);
|
||||
}
|
||||
} else {
|
||||
list_for_each_entry(swr_dev, &mstr->devices,
|
||||
dev_list) {
|
||||
ret = swr_set_device_group(swr_dev,
|
||||
SWR_GROUP_NONE);
|
||||
if (ret)
|
||||
dev_err(swrm->dev,
|
||||
"%s: set num ch failed\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&swrm->mlock);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_err(swrm->dev, "%s: swr master unknown id %d\n",
|
||||
__func__, id);
|
||||
|
|
|
@ -90,10 +90,12 @@ struct swr_mstr_ctrl {
|
|||
int irq;
|
||||
int num_enum_slaves;
|
||||
int slave_status;
|
||||
struct list_head mport_list;
|
||||
struct swr_mstr_port *mstr_port;
|
||||
struct list_head mport_list;
|
||||
int state;
|
||||
struct platform_device *pdev;
|
||||
int num_rx_chs;
|
||||
u8 num_cfg_devs;
|
||||
};
|
||||
|
||||
#endif /* _SWR_WCD_CTRL_H */
|
||||
|
|
|
@ -136,8 +136,12 @@
|
|||
#define SWRM_ENUMERATOR_SLAVE_DEV_ID_2(m) (SWRM_BASE_ADDRESS+0x534+0x8*m)
|
||||
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_ADDR(m) (SWRM_BASE_ADDRESS+0x101C+0x40*m)
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_RMSK 0x000007ff
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_RMSK 0x00ff07ff
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_SHFT 0
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK 0xff0000
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT 16
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_PHASE_BMSK 0xf800
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_PHASE_SHFT 11
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_BMSK 0x700
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_CLK_DIV_VALUE_SHFT 8
|
||||
#define SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK 0xF8
|
||||
|
|
|
@ -29,6 +29,14 @@ extern struct bus_type soundwire_type;
|
|||
*/
|
||||
#define SWR_MAX_MSTR_PORT_NUM (SWR_MAX_DEV_NUM * SWR_MAX_DEV_PORT_NUM)
|
||||
|
||||
/* Indicates soundwire devices group information */
|
||||
enum {
|
||||
SWR_GROUP_NONE = 0,
|
||||
SWR_GROUP_12 = 12,
|
||||
SWR_GROUP_13 = 13,
|
||||
SWR_BROADCAST = 15,
|
||||
};
|
||||
|
||||
/*
|
||||
* struct swr_port_info - represent soundwire frame shape
|
||||
* @dev_id: logical device number of the soundwire slave device
|
||||
|
@ -112,6 +120,7 @@ struct swr_reg {
|
|||
* @last_tid: size of table port_txn (can't grow beyond 256 since
|
||||
* tid is 8 bits)
|
||||
* @num_port: number of active ports on soundwire master
|
||||
* @gr_sid: slave id used by the group for write operations
|
||||
* @connect_port: callback for configuration of soundwire port(s)
|
||||
* @disconnect_port: callback for disable of soundwire port(s)
|
||||
* @read: callback for soundwire slave register read
|
||||
|
@ -131,6 +140,7 @@ struct swr_master {
|
|||
u8 last_tid;
|
||||
u8 num_port;
|
||||
u8 num_dev;
|
||||
u8 gr_sid;
|
||||
int (*connect_port)(struct swr_master *mstr, struct swr_params *txn);
|
||||
int (*disconnect_port)(struct swr_master *mstr, struct swr_params *txn);
|
||||
int (*read)(struct swr_master *mstr, u8 dev_num, u16 reg_addr,
|
||||
|
@ -159,6 +169,7 @@ static inline struct swr_master *to_swr_master(struct device *dev)
|
|||
* @dev: driver model representation of the device
|
||||
* @addr: represents "ea-addr" which is unique-id of soundwire slave
|
||||
* device
|
||||
* @group_id: group id supported by the slave device
|
||||
*/
|
||||
struct swr_device {
|
||||
char name[SOUNDWIRE_NAME_SIZE];
|
||||
|
@ -168,6 +179,7 @@ struct swr_device {
|
|||
u8 dev_num;
|
||||
struct device dev;
|
||||
unsigned long addr;
|
||||
u8 group_id;
|
||||
};
|
||||
|
||||
static inline struct swr_device *to_swr_device(struct device *dev)
|
||||
|
@ -270,6 +282,8 @@ extern int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port,
|
|||
extern int swr_disconnect_port(struct swr_device *dev,
|
||||
u8 *port_id, u8 num_port);
|
||||
|
||||
extern int swr_set_device_group(struct swr_device *swr_dev, u8 id);
|
||||
|
||||
extern int swr_driver_register(struct swr_driver *drv);
|
||||
|
||||
extern void swr_driver_unregister(struct swr_driver *drv);
|
||||
|
|
|
@ -4584,6 +4584,11 @@ static int tasha_codec_enable_swr(struct snd_soc_dapm_widget *w,
|
|||
if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
|
||||
tasha->rx_8_count)
|
||||
tasha->rx_8_count--;
|
||||
ch_cnt = tasha->rx_7_count + tasha->rx_8_count;
|
||||
|
||||
for (i = 0; i < tasha->nr; i++)
|
||||
swrm_wcd_notify(tasha->swr_ctrl_data[i].swr_pdev,
|
||||
SWR_SET_NUM_RX_CH, &ch_cnt);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -5475,30 +5480,56 @@ static const struct soc_enum cf_dec8_enum =
|
|||
static const struct soc_enum cf_int0_1_enum =
|
||||
SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2,
|
||||
rx_cf_text);
|
||||
|
||||
static const struct soc_enum cf_int1_1_enum =
|
||||
SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2,
|
||||
rx_cf_text);
|
||||
|
||||
static const struct soc_enum cf_int2_1_enum =
|
||||
SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2,
|
||||
rx_cf_text);
|
||||
|
||||
static const struct soc_enum cf_int3_1_enum =
|
||||
SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2,
|
||||
rx_cf_text);
|
||||
|
||||
static const struct soc_enum cf_int4_1_enum =
|
||||
SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2,
|
||||
rx_cf_text);
|
||||
|
||||
static const struct soc_enum cf_int5_1_enum =
|
||||
SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2,
|
||||
rx_cf_text);
|
||||
|
||||
static const struct soc_enum cf_int6_1_enum =
|
||||
SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2,
|
||||
rx_cf_text);
|
||||
|
||||
static const struct soc_enum cf_int7_1_enum =
|
||||
SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2,
|
||||
rx_cf_text);
|
||||
|
||||
static const struct soc_enum cf_int8_1_enum =
|
||||
SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2,
|
||||
rx_cf_text);
|
||||
static const struct snd_soc_dapm_route audio_map[] = {
|
||||
|
||||
/* MAD */
|
||||
|
@ -7518,14 +7549,23 @@ static const struct snd_kcontrol_new tasha_snd_controls[] = {
|
|||
SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
|
||||
|
||||
SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
|
||||
SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
|
||||
SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum),
|
||||
SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum),
|
||||
SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum),
|
||||
SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum),
|
||||
SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum),
|
||||
SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum),
|
||||
SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum),
|
||||
SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum),
|
||||
SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum),
|
||||
SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum),
|
||||
SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum),
|
||||
SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum),
|
||||
SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
|
||||
SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
|
||||
SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
|
||||
SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
|
||||
|
||||
SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
|
||||
tasha_get_iir_enable_audio_mixer, tasha_put_iir_enable_audio_mixer),
|
||||
|
@ -12160,9 +12200,33 @@ static int tasha_codec_remove(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tasha_codec_suspend(struct snd_soc_codec *codec)
|
||||
{
|
||||
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
|
||||
|
||||
pr_debug("%s:suspend of tasha codec\n", __func__);
|
||||
wcd9xxx_disable_static_supplies_to_optimum(tasha->wcd9xxx, pdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tasha_codec_resume(struct snd_soc_codec *codec)
|
||||
{
|
||||
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
|
||||
|
||||
pr_debug("%s:resume of tasha codec\n", __func__);
|
||||
wcd9xxx_enable_static_supplies_to_optimum(tasha->wcd9xxx, pdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_tasha = {
|
||||
.probe = tasha_codec_probe,
|
||||
.remove = tasha_codec_remove,
|
||||
.suspend = tasha_codec_suspend,
|
||||
.resume = tasha_codec_resume,
|
||||
.controls = tasha_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(tasha_snd_controls),
|
||||
.dapm_widgets = tasha_dapm_widgets,
|
||||
|
|
|
@ -431,7 +431,7 @@ static const struct reg_default wsa881x_vi_txfe_en[] = {
|
|||
static const struct reg_default wsa881x_vi_txfe_en_2_0[] = {
|
||||
{WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x85},
|
||||
{WSA881X_SPKR_PROT_ATEST2, 0x0A},
|
||||
{WSA881X_SPKR_PROT_FE_GAIN, 0xCF},
|
||||
{WSA881X_SPKR_PROT_FE_GAIN, 0x47},
|
||||
};
|
||||
|
||||
static int wsa881x_boost_ctrl(struct snd_soc_codec *codec, bool enable)
|
||||
|
@ -460,14 +460,26 @@ static int wsa881x_visense_txfe_ctrl(struct snd_soc_codec *codec, bool enable,
|
|||
__func__, enable, isense1_gain, isense2_gain, vsense_gain);
|
||||
|
||||
if (enable) {
|
||||
if (WSA881X_IS_2_0(wsa881x->version))
|
||||
if (WSA881X_IS_2_0(wsa881x->version)) {
|
||||
regmap_multi_reg_write(wsa881x->regmap,
|
||||
wsa881x_vi_txfe_en_2_0,
|
||||
ARRAY_SIZE(wsa881x_vi_txfe_en_2_0));
|
||||
else
|
||||
if (!wsa881x->comp_enable) {
|
||||
if (((snd_soc_read(codec, WSA881X_SPKR_DRV_GAIN)
|
||||
& 0xF0) >> 4) < G_15DB)
|
||||
snd_soc_update_bits(codec,
|
||||
WSA881X_SPKR_PROT_FE_GAIN,
|
||||
0xF8, 0xC8);
|
||||
else
|
||||
snd_soc_update_bits(codec,
|
||||
WSA881X_SPKR_PROT_FE_GAIN,
|
||||
0xF8, 0x40);
|
||||
}
|
||||
} else {
|
||||
regmap_multi_reg_write(wsa881x->regmap,
|
||||
wsa881x_vi_txfe_en,
|
||||
ARRAY_SIZE(wsa881x_vi_txfe_en));
|
||||
}
|
||||
} else {
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_PROT_FE_VSENSE_VCM,
|
||||
0x08, 0x08);
|
||||
|
@ -919,9 +931,12 @@ static void wsa881x_init(struct snd_soc_codec *codec)
|
|||
snd_soc_update_bits(codec, WSA881X_CDC_RST_CTL, 0x01, 0x01);
|
||||
|
||||
if (WSA881X_IS_2_0(wsa881x->version)) {
|
||||
snd_soc_update_bits(codec, WSA881X_CLOCK_CONFIG, 0x10, 0x10);
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0x02, 0x02);
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0xC0, 0x80);
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_MISC_CTL1, 0x06, 0x06);
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0xF0, 0x20);
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_BIAS_INT, 0xFF, 0x00);
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0xF0, 0x40);
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_PA_INT, 0x0E, 0x0E);
|
||||
snd_soc_update_bits(codec, WSA881X_BOOST_LOOP_STABILITY,
|
||||
0x03, 0x03);
|
||||
|
@ -932,8 +947,12 @@ static void wsa881x_init(struct snd_soc_codec *codec)
|
|||
0x0C, 0x04);
|
||||
snd_soc_update_bits(codec, WSA881X_BOOST_SLOPE_COMP_ISENSE_FB,
|
||||
0x03, 0x00);
|
||||
if (snd_soc_read(codec, WSA881X_OTP_REG_0))
|
||||
snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT1,
|
||||
0xF0, 0x70);
|
||||
snd_soc_update_bits(codec, WSA881X_BOOST_PRESET_OUT2,
|
||||
0xF0, 0x30);
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_DRV_EN, 0x08, 0x08);
|
||||
snd_soc_update_bits(codec, WSA881X_BOOST_PS_CTL, 0x80, 0x00);
|
||||
snd_soc_update_bits(codec, WSA881X_BOOST_CURRENT_LIMIT,
|
||||
0x0F, 0x08);
|
||||
snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0x30, 0x30);
|
||||
|
|
Loading…
Reference in New Issue