blob: 8cebb5064ad7494ed884905f03d9e72b83992539 [file] [log] [blame]
Satish kumar sugasie6b07af2018-05-25 17:48:45 -07001/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -08002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#include <linux/slimbus/slimbus.h>
13#include <btfm_slim.h>
14#include <btfm_slim_wcn3990.h>
15
16/* WCN3990 Port assignment */
17struct btfmslim_ch wcn3990_rxport[] = {
18 {.id = BTFM_BT_SCO_A2DP_SLIM_RX, .name = "SCO_A2P_Rx",
19 .port = CHRK_SB_PGD_PORT_RX_SCO},
20 {.id = BTFM_BT_SPLIT_A2DP_SLIM_RX, .name = "A2P_Rx",
21 .port = CHRK_SB_PGD_PORT_RX_A2P},
22 {.id = BTFM_SLIM_NUM_CODEC_DAIS, .name = "",
23 .port = BTFM_SLIM_PGD_PORT_LAST},
24};
25
26struct btfmslim_ch wcn3990_txport[] = {
27 {.id = BTFM_FM_SLIM_TX, .name = "FM_Tx1",
28 .port = CHRK_SB_PGD_PORT_TX1_FM},
29 {.id = BTFM_FM_SLIM_TX, .name = "FM_Tx2",
30 .port = CHRK_SB_PGD_PORT_TX2_FM},
31 {.id = BTFM_BT_SCO_SLIM_TX, .name = "SCO_Tx",
32 .port = CHRK_SB_PGD_PORT_TX_SCO},
33 {.id = BTFM_SLIM_NUM_CODEC_DAIS, .name = "",
34 .port = BTFM_SLIM_PGD_PORT_LAST},
35};
36
37/* Function description */
38int btfm_slim_chrk_hw_init(struct btfmslim *btfmslim)
39{
40 int ret = 0;
41 uint8_t reg_val;
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +053042 uint16_t reg;
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -080043
44 BTFMSLIM_DBG("");
45
46 if (!btfmslim)
47 return -EINVAL;
48
49 /* Get SB_SLAVE_HW_REV_MSB value*/
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +053050 reg = CHRK_SB_SLAVE_HW_REV_MSB;
51 ret = btfm_slim_read(btfmslim, reg, 1, &reg_val, IFD);
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -080052 if (ret) {
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +053053 BTFMSLIM_ERR("failed to read (%d) reg 0x%x", ret, reg);
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -080054 goto error;
55 }
56 BTFMSLIM_DBG("Major Rev: 0x%x, Minor Rev: 0x%x",
57 (reg_val & 0xF0) >> 4, (reg_val & 0x0F));
58
59 /* Get SB_SLAVE_HW_REV_LSB value*/
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +053060 reg = CHRK_SB_SLAVE_HW_REV_LSB;
61 ret = btfm_slim_read(btfmslim, reg, 1, &reg_val, IFD);
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -080062 if (ret) {
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +053063 BTFMSLIM_ERR("failed to read (%d) reg 0x%x", ret, reg);
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -080064 goto error;
65 }
66 BTFMSLIM_DBG("Step Rev: 0x%x", reg_val);
67
68error:
69 return ret;
70}
71
Rupesh Tatiya6fdd3f02017-04-18 19:25:11 +053072static inline int is_fm_port(uint8_t port_num)
73{
74 if (port_num == CHRK_SB_PGD_PORT_TX1_FM ||
Satish kumar sugasie6b07af2018-05-25 17:48:45 -070075 port_num == CHRKVER3_SB_PGD_PORT_TX1_FM ||
76 port_num == CHRKVER3_SB_PGD_PORT_TX2_FM ||
Rupesh Tatiya6fdd3f02017-04-18 19:25:11 +053077 port_num == CHRK_SB_PGD_PORT_TX2_FM)
78 return 1;
79 else
80 return 0;
81}
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -080082
83int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num,
84 uint8_t rxport, uint8_t enable)
85{
86 int ret = 0;
Rupesh Tatiyafc057b52017-06-20 15:06:29 +053087 uint8_t reg_val = 0, en;
Sungjun Parkea258e42017-10-18 19:08:25 -070088 uint8_t rxport_num = 0;
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -080089 uint16_t reg;
Satish Kodishalaead3f4e2017-12-22 21:55:57 +053090 uint8_t prev_reg_val = 0;
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -080091
Rupesh Tatiya3815c792017-02-17 12:58:01 +053092 BTFMSLIM_DBG("port(%d) enable(%d)", port_num, enable);
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -080093 if (rxport) {
Satish Kodishala530e0b62017-12-06 16:28:09 +053094 BTFMSLIM_DBG("sample rate is %d", btfmslim->sample_rate);
Satish Kodishalaead3f4e2017-12-22 21:55:57 +053095 if (enable) {
Satish Kodishala530e0b62017-12-06 16:28:09 +053096 /* For SCO Rx, A2DP Rx other than 44.1 and 88.2Khz */
Sungjun Parkea258e42017-10-18 19:08:25 -070097 if (port_num < 24) {
98 rxport_num = port_num - 16;
99 reg_val = 0x01 << rxport_num;
100 reg = CHRK_SB_PGD_RX_PORTn_MULTI_CHNL_0(
101 rxport_num);
102 } else {
103 rxport_num = port_num - 24;
104 reg_val = 0x01 << rxport_num;
105 reg = CHRK_SB_PGD_RX_PORTn_MULTI_CHNL_1(
106 rxport_num);
107 }
108
Satish Kodishalaead3f4e2017-12-22 21:55:57 +0530109 if (btfmslim->sample_rate == 44100 ||
110 btfmslim->sample_rate == 88200) {
111 BTFMSLIM_DBG("unsetting multichannel bit");
112 ret = btfm_slim_read(btfmslim, reg, 1,
113 &prev_reg_val, IFD);
114 if (ret < 0) {
115 BTFMSLIM_ERR("error %d reading", ret);
116 prev_reg_val = 0;
117 }
118 BTFMSLIM_DBG("prev_reg_val (%d) from reg(%x)",
119 prev_reg_val, reg);
120 reg_val = prev_reg_val & ~reg_val;
121 } else
122 BTFMSLIM_DBG("setting multichannel bit");
123
Satish Kodishala5095e402017-06-14 17:44:16 +0530124 BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)",
Sungjun Parkea258e42017-10-18 19:08:25 -0700125 reg_val, reg);
Satish Kodishala75fa6662017-05-01 19:17:06 +0530126 ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
127 if (ret) {
128 BTFMSLIM_ERR("failed to write (%d) reg 0x%x",
Sungjun Parkea258e42017-10-18 19:08:25 -0700129 ret, reg);
Satish Kodishala75fa6662017-05-01 19:17:06 +0530130 goto error;
131 }
132 }
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -0800133 /* Port enable */
134 reg = CHRK_SB_PGD_PORT_RX_CFGN(port_num - 0x10);
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +0530135 goto enable_disable_rxport;
136 }
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +0530137 if (!enable)
138 goto enable_disable_txport;
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -0800139
Satish Kodishala75fa6662017-05-01 19:17:06 +0530140 /* txport */
141 /* Multiple Channel Setting */
Rupesh Tatiya6fdd3f02017-04-18 19:25:11 +0530142 if (is_fm_port(port_num)) {
Satish kumar sugasie6b07af2018-05-25 17:48:45 -0700143 if (port_num == CHRKVER3_SB_PGD_PORT_TX1_FM)
144 reg_val = (0x1 << CHRKVER3_SB_PGD_PORT_TX1_FM);
145 else if (port_num == CHRKVER3_SB_PGD_PORT_TX2_FM)
146 reg_val = (0x1 << CHRKVER3_SB_PGD_PORT_TX2_FM);
147 else
148 reg_val = (0x1 << CHRK_SB_PGD_PORT_TX1_FM) |
149 (0x1 << CHRK_SB_PGD_PORT_TX2_FM);
150
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +0530151 reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num);
Satish kumar sugasie6b07af2018-05-25 17:48:45 -0700152 BTFMSLIM_INFO("writing reg_val (%d) to reg(%x)", reg_val, reg);
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +0530153 ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -0800154 if (ret) {
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +0530155 BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -0800156 goto error;
157 }
Satish Kodishalad9ee8612017-08-18 09:09:44 +0530158 } else if (port_num == CHRK_SB_PGD_PORT_TX_SCO) {
159 /* SCO Tx */
160 reg_val = 0x1 << CHRK_SB_PGD_PORT_TX_SCO;
161 reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num);
162 BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)",
163 reg_val, reg);
164 ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
165 if (ret) {
166 BTFMSLIM_ERR("failed to write (%d) reg 0x%x",
167 ret, reg);
168 goto error;
169 }
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -0800170 }
171
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +0530172 /* Enable Tx port hw auto recovery for underrun or overrun error */
173 reg_val = (CHRK_ENABLE_OVERRUN_AUTO_RECOVERY |
174 CHRK_ENABLE_UNDERRUN_AUTO_RECOVERY);
175 reg = CHRK_SB_PGD_PORT_TX_OR_UR_CFGN(port_num);
176 ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
177 if (ret) {
178 BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
179 goto error;
180 }
181
182enable_disable_txport:
183 /* Port enable */
184 reg = CHRK_SB_PGD_PORT_TX_CFGN(port_num);
185
186enable_disable_rxport:
Rupesh Tatiyafc057b52017-06-20 15:06:29 +0530187 if (enable)
188 en = CHRK_SB_PGD_PORT_ENABLE;
189 else
190 en = CHRK_SB_PGD_PORT_DISABLE;
191
192 if (is_fm_port(port_num))
193 reg_val = en | CHRK_SB_PGD_PORT_WM_L8;
Satish Kodishalad9ee8612017-08-18 09:09:44 +0530194 else if (port_num == CHRK_SB_PGD_PORT_TX_SCO)
195 reg_val = enable ? en | CHRK_SB_PGD_PORT_WM_L1 : en;
Rupesh Tatiyafc057b52017-06-20 15:06:29 +0530196 else
197 reg_val = enable ? en | CHRK_SB_PGD_PORT_WM_LB : en;
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -0800198
Satish Kodishalad9ee8612017-08-18 09:09:44 +0530199 if (enable && port_num == CHRK_SB_PGD_PORT_TX_SCO)
200 BTFMSLIM_INFO("programming SCO Tx with reg_val %d to reg 0x%x",
201 reg_val, reg);
202
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -0800203 ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
204 if (ret)
Rupesh Tatiya795ac6e2017-03-02 15:33:47 +0530205 BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
Mahesh Kumar Sharma41a4d382017-01-17 17:00:51 -0800206
207error:
208 return ret;
209}