codecs: add wcd9360 driver support in wcd9xxx core
Add changes to support wcd9360 audio codec driver in wcd9xxx common files. Change-Id: I5b9f9d592b6843d7887eb3954d079776ddf15764 Signed-off-by: Vidyakumar Athota <vathota@codeaurora.org>
This commit is contained in:
parent
9cbeb97832
commit
130934724f
6 changed files with 253 additions and 69 deletions
|
@ -119,6 +119,7 @@ enum codec_variant {
|
|||
WCD9335,
|
||||
WCD9326,
|
||||
WCD934X,
|
||||
WCD9360,
|
||||
};
|
||||
|
||||
enum wcd9xxx_slim_slave_addr_type {
|
||||
|
@ -297,6 +298,7 @@ enum wcd9xxx_chipid_major {
|
|||
TASHA_MAJOR = cpu_to_le16(0x0),
|
||||
TASHA2P0_MAJOR = cpu_to_le16(0x107),
|
||||
TAVIL_MAJOR = cpu_to_le16(0x108),
|
||||
PAHU_MAJOR = cpu_to_le16(0x109),
|
||||
};
|
||||
|
||||
enum codec_power_states {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2011-2018, 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
|
||||
|
@ -88,6 +88,7 @@ static const int wcd9xxx_cdc_types[] = {
|
|||
[WCD9330] = WCD9330,
|
||||
[WCD9335] = WCD9335,
|
||||
[WCD934X] = WCD934X,
|
||||
[WCD9360] = WCD9360,
|
||||
};
|
||||
|
||||
static const struct of_device_id wcd9xxx_of_match[] = {
|
||||
|
@ -327,7 +328,8 @@ int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg,
|
|||
struct slim_ele_access slim_msg;
|
||||
|
||||
mutex_lock(&wcd9xxx->io_lock);
|
||||
if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X) {
|
||||
if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X ||
|
||||
wcd9xxx->type == WCD9360) {
|
||||
ret = wcd9xxx_page_write(wcd9xxx, ®);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2018, 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
|
||||
|
@ -19,6 +19,8 @@
|
|||
|
||||
typedef int (*regmap_patch_fptr)(struct regmap *, int);
|
||||
|
||||
extern struct regmap_config wcd9360_regmap_config;
|
||||
|
||||
extern struct regmap_config wcd934x_regmap_config;
|
||||
extern int wcd934x_regmap_register_patch(struct regmap *regmap,
|
||||
int version);
|
||||
|
@ -32,6 +34,9 @@ static inline struct regmap_config *wcd9xxx_get_regmap_config(int type)
|
|||
struct regmap_config *regmap_config;
|
||||
|
||||
switch (type) {
|
||||
case WCD9360:
|
||||
regmap_config = &wcd9360_regmap_config;
|
||||
break;
|
||||
case WCD934X:
|
||||
regmap_config = &wcd934x_regmap_config;
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2018, 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
|
||||
|
@ -17,14 +17,18 @@
|
|||
#include <sound/soc.h>
|
||||
#include "wcd9xxx-resmgr-v2.h"
|
||||
#include "core.h"
|
||||
#include "wcd9335_registers.h"
|
||||
#include <asoc/wcd934x_registers.h>
|
||||
|
||||
#define WCD9XXX_RCO_CALIBRATION_DELAY_INC_US 5000
|
||||
/* This register is valid only for WCD9335 */
|
||||
#define WCD93XX_ANA_CLK_TOP 0x0602
|
||||
|
||||
#define WCD93XX_ANA_BIAS 0x0601
|
||||
#define WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41
|
||||
#define WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42
|
||||
|
||||
#define WCD93XX_CLK_SYS_MCLK_PRG 0x711
|
||||
#define WCD93XX_CODEC_RPM_CLK_GATE 0x002
|
||||
#define WCD93XX_ANA_RCO 0x603
|
||||
#define WCD93XX_ANA_BUCK_CTL 0x606
|
||||
|
||||
static const char *wcd_resmgr_clk_type_to_str(enum wcd_clock_type clk_type)
|
||||
{
|
||||
|
@ -44,13 +48,13 @@ static int wcd_resmgr_codec_reg_update_bits(struct wcd9xxx_resmgr_v2 *resmgr,
|
|||
bool change;
|
||||
int ret;
|
||||
|
||||
if (resmgr->codec_type == WCD934X) {
|
||||
/* Tavil does not support ANA_CLK_TOP register */
|
||||
if (reg == WCD9335_ANA_CLK_TOP)
|
||||
if (resmgr->codec_type != WCD9335) {
|
||||
/* Tavil and Pahu does not support ANA_CLK_TOP register */
|
||||
if (reg == WCD93XX_ANA_CLK_TOP)
|
||||
return 0;
|
||||
} else {
|
||||
/* Tasha does not support CLK_SYS_MCLK_PRG register */
|
||||
if (reg == WCD934X_CLK_SYS_MCLK_PRG)
|
||||
if (reg == WCD93XX_CLK_SYS_MCLK_PRG)
|
||||
return 0;
|
||||
}
|
||||
if (resmgr->codec) {
|
||||
|
@ -74,11 +78,11 @@ static int wcd_resmgr_codec_reg_read(struct wcd9xxx_resmgr_v2 *resmgr,
|
|||
{
|
||||
int val, ret;
|
||||
|
||||
if (resmgr->codec_type == WCD934X) {
|
||||
if (reg == WCD9335_ANA_CLK_TOP)
|
||||
if (resmgr->codec_type != WCD9335) {
|
||||
if (reg == WCD93XX_ANA_CLK_TOP)
|
||||
return 0;
|
||||
} else {
|
||||
if (reg == WCD934X_CLK_SYS_MCLK_PRG)
|
||||
if (reg == WCD93XX_CLK_SYS_MCLK_PRG)
|
||||
return 0;
|
||||
}
|
||||
if (resmgr->codec) {
|
||||
|
@ -242,26 +246,26 @@ static int wcd_resmgr_enable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
|
||||
if (++resmgr->clk_mclk_users == 1) {
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD9335_ANA_CLK_TOP, 0x80, 0x80);
|
||||
WCD93XX_ANA_CLK_TOP, 0x80, 0x80);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD9335_ANA_CLK_TOP, 0x08, 0x00);
|
||||
WCD93XX_ANA_CLK_TOP, 0x08, 0x00);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD9335_ANA_CLK_TOP, 0x04, 0x04);
|
||||
if (resmgr->codec_type == WCD934X) {
|
||||
WCD93XX_ANA_CLK_TOP, 0x04, 0x04);
|
||||
if (resmgr->codec_type != WCD9335) {
|
||||
/*
|
||||
* In tavil clock contrl register is changed
|
||||
* to CLK_SYS_MCLK_PRG
|
||||
*/
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG, 0x80, 0x80);
|
||||
WCD93XX_CLK_SYS_MCLK_PRG, 0x80, 0x80);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG, 0x30, 0x10);
|
||||
WCD93XX_CLK_SYS_MCLK_PRG, 0x30, 0x10);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x00);
|
||||
WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x00);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG, 0x01, 0x01);
|
||||
WCD93XX_CLK_SYS_MCLK_PRG, 0x01, 0x01);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x00);
|
||||
WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x00);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
|
||||
0x01, 0x01);
|
||||
|
@ -269,10 +273,7 @@ static int wcd_resmgr_enable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL,
|
||||
0x01, 0x01);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL,
|
||||
0x01, 0x01);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CODEC_RPM_CLK_GATE, 0x03, 0x00);
|
||||
WCD93XX_CODEC_RPM_CLK_GATE, 0x03, 0x00);
|
||||
} else {
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
|
||||
|
@ -308,28 +309,28 @@ static int wcd_resmgr_disable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
if (resmgr->clk_rco_users > 0) {
|
||||
/* MCLK to RCO switch */
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD9335_ANA_CLK_TOP,
|
||||
WCD93XX_ANA_CLK_TOP,
|
||||
0x08, 0x08);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x02);
|
||||
WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x02);
|
||||
/* Disable clock buffer */
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG, 0x80, 0x00);
|
||||
WCD93XX_CLK_SYS_MCLK_PRG, 0x80, 0x00);
|
||||
resmgr->clk_type = WCD_CLK_RCO;
|
||||
} else {
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD9335_ANA_CLK_TOP,
|
||||
WCD93XX_ANA_CLK_TOP,
|
||||
0x04, 0x00);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG, 0x81, 0x00);
|
||||
WCD93XX_CLK_SYS_MCLK_PRG, 0x81, 0x00);
|
||||
resmgr->clk_type = WCD_CLK_OFF;
|
||||
}
|
||||
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP,
|
||||
0x80, 0x00);
|
||||
}
|
||||
|
||||
if ((resmgr->codec_type == WCD934X) &&
|
||||
if ((resmgr->codec_type != WCD9335) &&
|
||||
(resmgr->clk_type == WCD_CLK_OFF))
|
||||
wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL);
|
||||
|
||||
|
@ -342,15 +343,15 @@ static int wcd_resmgr_disable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
|
||||
static void wcd_resmgr_set_buck_accuracy(struct wcd9xxx_resmgr_v2 *resmgr)
|
||||
{
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
|
||||
0x02, 0x02);
|
||||
/* 100us sleep needed after HIGH_ACCURACY_PRE_EN1 */
|
||||
usleep_range(100, 110);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
|
||||
0x01, 0x01);
|
||||
/* 100us sleep needed after HIGH_ACCURACY_PRE_EN2 */
|
||||
usleep_range(100, 110);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
|
||||
0x04, 0x04);
|
||||
/* 100us sleep needed after HIGH_ACCURACY_EN */
|
||||
usleep_range(100, 110);
|
||||
|
@ -373,9 +374,9 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
/* RCO Enable */
|
||||
if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL) {
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD9335_ANA_RCO,
|
||||
0x80, 0x80);
|
||||
if (resmgr->codec_type == WCD934X)
|
||||
WCD93XX_ANA_RCO,
|
||||
0x80, 0x80);
|
||||
if (resmgr->codec_type != WCD9335)
|
||||
wcd_resmgr_set_buck_accuracy(resmgr);
|
||||
}
|
||||
|
||||
|
@ -384,7 +385,7 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
* requirements
|
||||
*/
|
||||
usleep_range(20, 25);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
|
||||
0x40, 0x40);
|
||||
/*
|
||||
* 20us required after RCO is enabled as per HW
|
||||
|
@ -392,20 +393,20 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
*/
|
||||
usleep_range(20, 25);
|
||||
/* RCO Calibration */
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
|
||||
0x04, 0x04);
|
||||
if (resmgr->codec_type == WCD934X)
|
||||
if (resmgr->codec_type != WCD9335)
|
||||
/*
|
||||
* For wcd934x codec, 20us sleep is needed
|
||||
* For wcd934x and wcd936x codecs, 20us sleep is needed
|
||||
* after enabling RCO calibration
|
||||
*/
|
||||
usleep_range(20, 25);
|
||||
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
|
||||
0x04, 0x00);
|
||||
if (resmgr->codec_type == WCD934X)
|
||||
if (resmgr->codec_type != WCD9335)
|
||||
/*
|
||||
* For wcd934x codec, 20us sleep is needed
|
||||
* For wcd934x and wcd936x codecs, 20us sleep is needed
|
||||
* after disabling RCO calibration
|
||||
*/
|
||||
usleep_range(20, 25);
|
||||
|
@ -413,7 +414,7 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
/* RCO calibration takes app. 5ms to complete */
|
||||
usleep_range(WCD9XXX_RCO_CALIBRATION_DELAY_INC_US,
|
||||
WCD9XXX_RCO_CALIBRATION_DELAY_INC_US + 100);
|
||||
if (wcd_resmgr_codec_reg_read(resmgr, WCD9335_ANA_RCO) & 0x02)
|
||||
if (wcd_resmgr_codec_reg_read(resmgr, WCD93XX_ANA_RCO) & 0x02)
|
||||
rco_cal_done = false;
|
||||
|
||||
WARN((!rco_cal_done), "RCO Calibration failed\n");
|
||||
|
@ -421,10 +422,10 @@ static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
/* Switch MUX to RCO */
|
||||
if (resmgr->clk_mclk_users == 1) {
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD9335_ANA_CLK_TOP,
|
||||
WCD93XX_ANA_CLK_TOP,
|
||||
0x08, 0x08);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG,
|
||||
WCD93XX_CLK_SYS_MCLK_PRG,
|
||||
0x02, 0x02);
|
||||
resmgr->clk_type = WCD_CLK_RCO;
|
||||
}
|
||||
|
@ -449,35 +450,35 @@ static int wcd_resmgr_disable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
|
|||
|
||||
if ((resmgr->clk_rco_users == 0) &&
|
||||
(resmgr->clk_type == WCD_CLK_RCO)) {
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP,
|
||||
0x08, 0x00);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG,
|
||||
WCD93XX_CLK_SYS_MCLK_PRG,
|
||||
0x02, 0x00);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP,
|
||||
0x04, 0x00);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
|
||||
0x40, 0x00);
|
||||
if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL)
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD9335_ANA_RCO,
|
||||
WCD93XX_ANA_RCO,
|
||||
0x80, 0x00);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD934X_CLK_SYS_MCLK_PRG,
|
||||
WCD93XX_CLK_SYS_MCLK_PRG,
|
||||
0x01, 0x00);
|
||||
resmgr->clk_type = WCD_CLK_OFF;
|
||||
} else if ((resmgr->clk_rco_users == 0) &&
|
||||
(resmgr->clk_mclk_users)) {
|
||||
/* Disable RCO while MCLK is ON */
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
|
||||
0x40, 0x00);
|
||||
if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL)
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr,
|
||||
WCD9335_ANA_RCO,
|
||||
WCD93XX_ANA_RCO,
|
||||
0x80, 0x00);
|
||||
}
|
||||
|
||||
if ((resmgr->codec_type == WCD934X) &&
|
||||
if ((resmgr->codec_type != WCD9335) &&
|
||||
(resmgr->clk_type == WCD_CLK_OFF))
|
||||
wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL);
|
||||
|
||||
|
@ -530,28 +531,28 @@ void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr,
|
|||
return;
|
||||
|
||||
if (sido_src == SIDO_SOURCE_INTERNAL) {
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
|
||||
0x04, 0x00);
|
||||
usleep_range(100, 110);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
|
||||
0x03, 0x00);
|
||||
usleep_range(100, 110);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
|
||||
0x80, 0x00);
|
||||
usleep_range(100, 110);
|
||||
resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
|
||||
pr_debug("%s: sido input src to internal\n", __func__);
|
||||
} else if (sido_src == SIDO_SOURCE_RCO_BG) {
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
|
||||
0x80, 0x80);
|
||||
usleep_range(100, 110);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
|
||||
0x02, 0x02);
|
||||
usleep_range(100, 110);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
|
||||
0x01, 0x01);
|
||||
usleep_range(100, 110);
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
|
||||
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
|
||||
0x04, 0x04);
|
||||
usleep_range(100, 110);
|
||||
resmgr->sido_input_src = SIDO_SOURCE_RCO_BG;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2017-2018, 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
|
||||
|
@ -22,6 +22,8 @@
|
|||
#include "wcd9335_irq.h"
|
||||
#include <asoc/wcd934x_registers.h>
|
||||
#include "wcd934x/wcd934x_irq.h"
|
||||
#include <asoc/wcd9360-registers.h>
|
||||
#include "wcd9360/wcd9360-irq.h"
|
||||
|
||||
/* wcd9335 interrupt table */
|
||||
static const struct intr_data wcd9335_intr_table[] = {
|
||||
|
@ -86,6 +88,25 @@ static const struct intr_data wcd934x_intr_table[] = {
|
|||
{WCD934X_IRQ_VBAT_RESTORE, false},
|
||||
};
|
||||
|
||||
static const struct intr_data wcd9360_intr_table[] = {
|
||||
{WCD9XXX_IRQ_SLIMBUS, false},
|
||||
{WCD9360_IRQ_MISC, false},
|
||||
{WCD9360_IRQ_LDO_RXTX_SCD, false},
|
||||
{WCD9360_IRQ_EAR_PA_SCD, false},
|
||||
{WCD9360_IRQ_AUX_PA_SCD, false},
|
||||
{WCD9360_IRQ_EAR_PA_CNP_COMPLETE, false},
|
||||
{WCD9360_IRQ_AUX_PA_CNP_COMPLETE, false},
|
||||
{WCD9360_IRQ_RESERVED_3, false},
|
||||
{WCD9360_IRQ_SOUNDWIRE, false},
|
||||
{WCD9360_IRQ_RCO_ERROR, false},
|
||||
{WCD9360_IRQ_CPE_ERROR, false},
|
||||
{WCD9360_IRQ_MAD_AUDIO, false},
|
||||
{WCD9360_IRQ_MAD_BEACON, false},
|
||||
{WCD9360_IRQ_CPE1_INTR, true},
|
||||
{WCD9360_IRQ_RESERVED_4, false},
|
||||
{WCD9360_IRQ_MAD_ULTRASOUND, false},
|
||||
};
|
||||
|
||||
/*
|
||||
* wcd9335_bring_down: Bringdown WCD Codec
|
||||
*
|
||||
|
@ -384,11 +405,143 @@ static int wcd934x_get_cdc_info(struct wcd9xxx *wcd9xxx,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* wcd9360_bring_down: Bringdown WCD Codec
|
||||
*
|
||||
* @wcd9xxx: Pointer to wcd9xxx structure
|
||||
*
|
||||
* Returns 0 for success or negative error code for failure
|
||||
*/
|
||||
static int wcd9360_bring_down(struct wcd9xxx *wcd9xxx)
|
||||
{
|
||||
if (!wcd9xxx || !wcd9xxx->regmap)
|
||||
return -EINVAL;
|
||||
|
||||
regmap_write(wcd9xxx->regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
|
||||
0x04);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* wcd9360_bring_up: Bringup WCD Codec
|
||||
*
|
||||
* @wcd9xxx: Pointer to the wcd9xxx structure
|
||||
*
|
||||
* Returns 0 for success or negative error code for failure
|
||||
*/
|
||||
static int wcd9360_bring_up(struct wcd9xxx *wcd9xxx)
|
||||
{
|
||||
struct regmap *wcd_regmap;
|
||||
|
||||
if (!wcd9xxx)
|
||||
return -EINVAL;
|
||||
|
||||
if (!wcd9xxx->regmap) {
|
||||
dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
wcd_regmap = wcd9xxx->regmap;
|
||||
|
||||
regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x01);
|
||||
regmap_write(wcd_regmap, WCD9360_SIDO_NEW_VOUT_A_STARTUP, 0x19);
|
||||
regmap_write(wcd_regmap, WCD9360_SIDO_NEW_VOUT_D_STARTUP, 0x15);
|
||||
/* Add 1msec delay for VOUT to settle */
|
||||
usleep_range(1000, 1100);
|
||||
regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
|
||||
regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
|
||||
regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x3);
|
||||
regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x7);
|
||||
regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* wcd9360_get_cdc_info: Get codec specific information
|
||||
*
|
||||
* @wcd9xxx: pointer to wcd9xxx structure
|
||||
* @wcd_type: pointer to wcd9xxx_codec_type structure
|
||||
*
|
||||
* Returns 0 for success or negative error code for failure
|
||||
*/
|
||||
static int wcd9360_get_cdc_info(struct wcd9xxx *wcd9xxx,
|
||||
struct wcd9xxx_codec_type *wcd_type)
|
||||
{
|
||||
u16 id_minor, id_major;
|
||||
struct regmap *wcd_regmap;
|
||||
int rc, version = -1;
|
||||
|
||||
if (!wcd9xxx || !wcd_type)
|
||||
return -EINVAL;
|
||||
|
||||
if (!wcd9xxx->regmap) {
|
||||
dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
wcd_regmap = wcd9xxx->regmap;
|
||||
|
||||
rc = regmap_bulk_read(wcd_regmap, WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
|
||||
(u8 *)&id_minor, sizeof(u16));
|
||||
if (rc)
|
||||
return -EINVAL;
|
||||
|
||||
rc = regmap_bulk_read(wcd_regmap, WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2,
|
||||
(u8 *)&id_major, sizeof(u16));
|
||||
if (rc)
|
||||
return -EINVAL;
|
||||
|
||||
dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n",
|
||||
__func__, id_major, id_minor);
|
||||
|
||||
if (id_major != PAHU_MAJOR)
|
||||
goto version_unknown;
|
||||
|
||||
/*
|
||||
* As fine version info cannot be retrieved before pahu probe.
|
||||
* Assign coarse versions for possible future use before Pahu probe.
|
||||
*/
|
||||
if (id_minor == cpu_to_le16(0))
|
||||
version = PAHU_VERSION_1_0;
|
||||
|
||||
version_unknown:
|
||||
if (version < 0)
|
||||
dev_err(wcd9xxx->dev, "%s: wcd934x version unknown\n",
|
||||
__func__);
|
||||
|
||||
/* Fill codec type info */
|
||||
wcd_type->id_major = id_major;
|
||||
wcd_type->id_minor = id_minor;
|
||||
wcd_type->num_irqs = WCD9360_NUM_IRQS;
|
||||
wcd_type->version = version;
|
||||
wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1;
|
||||
wcd_type->i2c_chip_status = 0x01;
|
||||
wcd_type->intr_tbl = wcd9360_intr_table;
|
||||
wcd_type->intr_tbl_size = ARRAY_SIZE(wcd934x_intr_table);
|
||||
|
||||
wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] =
|
||||
WCD9360_INTR_PIN1_STATUS0;
|
||||
wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] =
|
||||
WCD9360_INTR_PIN1_CLEAR0;
|
||||
wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] =
|
||||
WCD9360_INTR_PIN1_MASK0;
|
||||
wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] =
|
||||
WCD9360_INTR_LEVEL0;
|
||||
wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] =
|
||||
WCD9360_INTR_CLR_COMMIT;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
codec_bringdown_fn wcd9xxx_bringdown_fn(int type)
|
||||
{
|
||||
codec_bringdown_fn cdc_bdown_fn;
|
||||
|
||||
switch (type) {
|
||||
case WCD9360:
|
||||
cdc_bdown_fn = wcd9360_bring_down;
|
||||
break;
|
||||
case WCD934X:
|
||||
cdc_bdown_fn = wcd934x_bring_down;
|
||||
break;
|
||||
|
@ -408,6 +561,9 @@ codec_bringup_fn wcd9xxx_bringup_fn(int type)
|
|||
codec_bringup_fn cdc_bup_fn;
|
||||
|
||||
switch (type) {
|
||||
case WCD9360:
|
||||
cdc_bup_fn = wcd9360_bring_up;
|
||||
break;
|
||||
case WCD934X:
|
||||
cdc_bup_fn = wcd934x_bring_up;
|
||||
break;
|
||||
|
@ -427,6 +583,9 @@ codec_type_fn wcd9xxx_get_codec_info_fn(int type)
|
|||
codec_type_fn cdc_type_fn;
|
||||
|
||||
switch (type) {
|
||||
case WCD9360:
|
||||
cdc_type_fn = wcd9360_get_cdc_info;
|
||||
break;
|
||||
case WCD934X:
|
||||
cdc_type_fn = wcd934x_get_cdc_info;
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2018, 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
|
||||
|
@ -38,6 +38,16 @@
|
|||
|
||||
static enum wcd9xxx_intf_status wcd9xxx_intf = -1;
|
||||
|
||||
static struct mfd_cell pahu_devs[] = {
|
||||
{
|
||||
.name = "qcom-wcd-pinctrl",
|
||||
.of_compatible = "qcom,wcd-pinctrl",
|
||||
},
|
||||
{
|
||||
.name = "pahu_codec",
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell tavil_devs[] = {
|
||||
{
|
||||
.name = "qcom-wcd-pinctrl",
|
||||
|
@ -467,7 +477,8 @@ int wcd9xxx_page_write(struct wcd9xxx *wcd9xxx, unsigned short *reg)
|
|||
unsigned short c_reg, reg_addr;
|
||||
u8 pg_num, prev_pg_num;
|
||||
|
||||
if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X)
|
||||
if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X &&
|
||||
wcd9xxx->type != WCD9360)
|
||||
return ret;
|
||||
|
||||
c_reg = *reg;
|
||||
|
@ -864,6 +875,10 @@ int wcd9xxx_get_codec_info(struct device *dev)
|
|||
}
|
||||
|
||||
switch (wcd9xxx->type) {
|
||||
case WCD9360:
|
||||
cinfo->dev = pahu_devs;
|
||||
cinfo->size = ARRAY_SIZE(pahu_devs);
|
||||
break;
|
||||
case WCD934X:
|
||||
cinfo->dev = tavil_devs;
|
||||
cinfo->size = ARRAY_SIZE(tavil_devs);
|
||||
|
|
Loading…
Add table
Reference in a new issue