Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 1 | /* Copyright (c) 2012, Code Aurora Forum. All rights reserved. |
| 2 | * |
| 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/slab.h> |
| 13 | #include <linux/mutex.h> |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 14 | #include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h> |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 15 | #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h> |
| 16 | |
| 17 | #define WCD9XXX_CHIP_ID_TAIKO 0x00000201 |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 18 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 19 | struct wcd9xxx_slim_sch_rx { |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 20 | u32 sph; |
| 21 | u32 ch_num; |
| 22 | u16 ch_h; |
| 23 | u16 grph; |
| 24 | }; |
| 25 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 26 | struct wcd9xxx_slim_sch_tx { |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 27 | u32 sph; |
| 28 | u32 ch_num; |
| 29 | u16 ch_h; |
| 30 | u16 grph; |
| 31 | }; |
| 32 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 33 | struct wcd9xxx_slim_sch { |
| 34 | struct wcd9xxx_slim_sch_rx rx[SLIM_MAX_RX_PORTS]; |
| 35 | struct wcd9xxx_slim_sch_tx tx[SLIM_MAX_TX_PORTS]; |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 36 | |
| 37 | u16 rx_port_start_offset; |
| 38 | u16 num_rx_slave_port; |
| 39 | u16 port_ch_0_start_port_id; |
| 40 | u16 port_ch_0_end_port_id; |
| 41 | u16 pgd_tx_port_ch_1_end_port_id; |
| 42 | u16 rx_port_ch_reg_base; |
| 43 | u16 port_tx_cfg_reg_base; |
| 44 | u16 port_rx_cfg_reg_base; |
| 45 | int number_of_tx_slave_dev_ports; |
| 46 | int number_of_rx_slave_dev_ports; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 47 | }; |
| 48 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 49 | static struct wcd9xxx_slim_sch sh_ch; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 50 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 51 | static int wcd9xxx_alloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 52 | u8 wcd9xxx_pgd_la); |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 53 | static int wcd9xxx_alloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx, |
| 54 | u8 wcd9xxx_pgd_la); |
| 55 | static int wcd9xxx_dealloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx); |
| 56 | static int wcd9xxx_dealloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 57 | |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 58 | static int wcd9xxx_configure_ports(struct wcd9xxx *wcd9xxx) |
| 59 | { |
| 60 | int i; |
| 61 | u32 id; |
| 62 | for (i = 0; i < 4; i++) |
| 63 | ((u8 *)&id)[i] = wcd9xxx_reg_read(wcd9xxx, |
| 64 | WCD9XXX_A_CHIP_ID_BYTE_0 + i); |
| 65 | id = cpu_to_be32(id); |
| 66 | pr_debug("%s: chip id 0x%08x\n", __func__, id); |
| 67 | if (id != WCD9XXX_CHIP_ID_TAIKO) { |
| 68 | sh_ch.rx_port_start_offset = |
| 69 | TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS; |
| 70 | sh_ch.num_rx_slave_port = |
| 71 | TABLA_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS; |
| 72 | sh_ch.port_ch_0_start_port_id = |
| 73 | TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID; |
| 74 | sh_ch.port_ch_0_end_port_id = |
| 75 | TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID; |
| 76 | sh_ch.pgd_tx_port_ch_1_end_port_id = |
| 77 | TABLA_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID; |
| 78 | |
| 79 | sh_ch.rx_port_ch_reg_base = |
| 80 | 0x180 + (TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS * 4); |
| 81 | sh_ch.port_rx_cfg_reg_base = |
| 82 | 0x040 + (TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS); |
| 83 | sh_ch.port_tx_cfg_reg_base = 0x040; |
| 84 | |
| 85 | sh_ch.number_of_tx_slave_dev_ports = |
| 86 | TABLA_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS; |
| 87 | sh_ch.number_of_rx_slave_dev_ports = |
| 88 | TABLA_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS; |
| 89 | } else { |
| 90 | sh_ch.rx_port_start_offset = |
| 91 | TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS; |
| 92 | sh_ch.num_rx_slave_port = |
| 93 | TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS; |
| 94 | sh_ch.port_ch_0_start_port_id = |
| 95 | TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID; |
| 96 | sh_ch.port_ch_0_end_port_id = |
| 97 | TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID; |
| 98 | sh_ch.pgd_tx_port_ch_1_end_port_id = |
| 99 | TAIKO_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID; |
| 100 | |
| 101 | sh_ch.rx_port_ch_reg_base = 0x180; |
| 102 | sh_ch.port_rx_cfg_reg_base = 0x040; |
| 103 | sh_ch.port_tx_cfg_reg_base = 0x050; |
| 104 | |
| 105 | sh_ch.number_of_tx_slave_dev_ports = |
| 106 | TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS; |
| 107 | sh_ch.number_of_rx_slave_dev_ports = |
| 108 | TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS; |
| 109 | } |
| 110 | |
| 111 | return 0; |
| 112 | } |
| 113 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 114 | int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 115 | { |
| 116 | int ret = 0; |
| 117 | |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 118 | ret = wcd9xxx_configure_ports(wcd9xxx); |
| 119 | if (ret) { |
| 120 | pr_err("%s: Failed to configure register address offset\n", |
| 121 | __func__); |
| 122 | goto err; |
| 123 | } |
| 124 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 125 | ret = wcd9xxx_alloc_slim_sh_ch_rx(wcd9xxx, wcd9xxx_pgd_la); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 126 | if (ret) { |
| 127 | pr_err("%s: Failed to alloc rx slimbus shared channels\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 128 | __func__); |
| 129 | goto err; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 130 | } |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 131 | ret = wcd9xxx_alloc_slim_sh_ch_tx(wcd9xxx, wcd9xxx_pgd_la); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 132 | if (ret) { |
| 133 | pr_err("%s: Failed to alloc tx slimbus shared channels\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 134 | __func__); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 135 | goto tx_err; |
| 136 | } |
| 137 | return 0; |
| 138 | tx_err: |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 139 | wcd9xxx_dealloc_slim_sh_ch_rx(wcd9xxx); |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 140 | err: |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 141 | return ret; |
| 142 | } |
| 143 | |
| 144 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 145 | int wcd9xxx_deinit_slimslave(struct wcd9xxx *wcd9xxx) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 146 | { |
| 147 | int ret = 0; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 148 | ret = wcd9xxx_dealloc_slim_sh_ch_rx(wcd9xxx); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 149 | if (ret < 0) { |
| 150 | pr_err("%s: fail to dealloc rx slim ports\n", __func__); |
| 151 | goto err; |
| 152 | } |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 153 | ret = wcd9xxx_dealloc_slim_sh_ch_tx(wcd9xxx); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 154 | if (ret < 0) { |
| 155 | pr_err("%s: fail to dealloc tx slim ports\n", __func__); |
| 156 | goto err; |
| 157 | } |
| 158 | err: |
| 159 | return ret; |
| 160 | } |
| 161 | |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 162 | int wcd9xxx_get_channel(struct wcd9xxx *wcd9xxx, unsigned int *rx_ch, |
| 163 | unsigned int *tx_ch) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 164 | { |
| 165 | int ch_idx = 0; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 166 | struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx; |
| 167 | struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 168 | |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 169 | for (ch_idx = 0; ch_idx < sh_ch.number_of_rx_slave_dev_ports; ch_idx++) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 170 | rx_ch[ch_idx] = rx[ch_idx].ch_num; |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 171 | for (ch_idx = 0; ch_idx < sh_ch.number_of_tx_slave_dev_ports; ch_idx++) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 172 | tx_ch[ch_idx] = tx[ch_idx].ch_num; |
| 173 | return 0; |
| 174 | } |
| 175 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 176 | static int wcd9xxx_alloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 177 | u8 wcd9xxx_pgd_la) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 178 | { |
| 179 | int ret = 0; |
| 180 | u8 ch_idx ; |
| 181 | u16 slave_port_id = 0; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 182 | struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 183 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 184 | /* |
| 185 | * DSP requires channel number to be between 128 and 255. |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 186 | */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 187 | pr_debug("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la); |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 188 | for (ch_idx = 0; ch_idx < sh_ch.number_of_rx_slave_dev_ports; |
| 189 | ch_idx++) { |
| 190 | slave_port_id = (ch_idx + sh_ch.rx_port_start_offset); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 191 | rx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 192 | ret = slim_get_slaveport(wcd9xxx_pgd_la, slave_port_id, |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 193 | &rx[ch_idx].sph, SLIM_SINK); |
| 194 | if (ret < 0) { |
| 195 | pr_err("%s: slave port failure id[%d] ret[%d]\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 196 | __func__, slave_port_id, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 197 | goto err; |
| 198 | } |
| 199 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 200 | ret = slim_query_ch(wcd9xxx->slim, rx[ch_idx].ch_num, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 201 | &rx[ch_idx].ch_h); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 202 | if (ret < 0) { |
| 203 | pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 204 | __func__, rx[ch_idx].ch_num, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 205 | goto err; |
| 206 | } |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 207 | pr_debug("%s:ch_num=%d ch_h=%d sph=%d la=%d slave_port_id %d\n", |
| 208 | __func__, rx[ch_idx].ch_num, rx[ch_idx].ch_h, |
| 209 | rx[ch_idx].sph, wcd9xxx_pgd_la, slave_port_id); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 210 | } |
| 211 | err: |
| 212 | return ret; |
| 213 | } |
| 214 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 215 | static int wcd9xxx_alloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 216 | u8 wcd9xxx_pgd_la) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 217 | { |
| 218 | int ret = 0; |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 219 | u8 ch_idx; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 220 | struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 221 | u16 slave_port_id = 0; |
| 222 | |
Swaminathan Sathappan | 362a17c | 2012-04-25 18:09:46 -0700 | [diff] [blame] | 223 | pr_debug("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 224 | /* DSP requires channel number to be between 128 and 255. For RX port |
| 225 | * use channel numbers from 138 to 144, for TX port |
| 226 | * use channel numbers from 128 to 137 |
| 227 | */ |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 228 | for (ch_idx = 0; ch_idx < sh_ch.number_of_tx_slave_dev_ports; |
| 229 | ch_idx++) { |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 230 | slave_port_id = ch_idx; |
| 231 | tx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 232 | ret = slim_get_slaveport(wcd9xxx_pgd_la, slave_port_id, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 233 | &tx[ch_idx].sph, SLIM_SRC); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 234 | if (ret < 0) { |
| 235 | pr_err("%s: slave port failure id[%d] ret[%d]\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 236 | __func__, slave_port_id, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 237 | goto err; |
| 238 | } |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 239 | ret = slim_query_ch(wcd9xxx->slim, tx[ch_idx].ch_num, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 240 | &tx[ch_idx].ch_h); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 241 | if (ret < 0) { |
| 242 | pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 243 | __func__, tx[ch_idx].ch_num, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 244 | goto err; |
| 245 | } |
| 246 | } |
| 247 | err: |
| 248 | return ret; |
| 249 | } |
| 250 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 251 | static int wcd9xxx_dealloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 252 | { |
| 253 | int idx = 0; |
| 254 | int ret = 0; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 255 | struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 256 | /* slim_dealloc_ch */ |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 257 | for (idx = 0; idx < sh_ch.number_of_rx_slave_dev_ports; idx++) { |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 258 | ret = slim_dealloc_ch(wcd9xxx->slim, rx[idx].ch_h); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 259 | if (ret < 0) { |
| 260 | pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n", |
| 261 | __func__, ret, rx[idx].ch_h); |
| 262 | } |
| 263 | } |
| 264 | memset(sh_ch.rx, 0, sizeof(sh_ch.rx)); |
| 265 | return ret; |
| 266 | } |
| 267 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 268 | static int wcd9xxx_dealloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 269 | { |
| 270 | int idx = 0; |
| 271 | int ret = 0; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 272 | struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 273 | /* slim_dealloc_ch */ |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 274 | for (idx = 0; idx < sh_ch.number_of_tx_slave_dev_ports; idx++) { |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 275 | ret = slim_dealloc_ch(wcd9xxx->slim, tx[idx].ch_h); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 276 | if (ret < 0) { |
| 277 | pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n", |
| 278 | __func__, ret, tx[idx].ch_h); |
| 279 | } |
| 280 | } |
| 281 | memset(sh_ch.tx, 0, sizeof(sh_ch.tx)); |
| 282 | return ret; |
| 283 | } |
| 284 | |
| 285 | /* Enable slimbus slave device for RX path */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 286 | int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 287 | unsigned int ch_cnt, unsigned int rate) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 288 | { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 289 | u8 i; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 290 | u16 grph; |
| 291 | u32 sph[SLIM_MAX_RX_PORTS] = {0}; |
| 292 | u16 ch_h[SLIM_MAX_RX_PORTS] = {0}; |
| 293 | u16 slave_port_id; |
| 294 | u8 payload_rx = 0, wm_payload = 0; |
| 295 | int ret, idx = 0; |
| 296 | unsigned short multi_chan_cfg_reg_addr; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 297 | struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 298 | struct slim_ch prop; |
| 299 | |
| 300 | /* Configure slave interface device */ |
Swaminathan Sathappan | 362a17c | 2012-04-25 18:09:46 -0700 | [diff] [blame] | 301 | pr_debug("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 302 | |
| 303 | for (i = 0; i < ch_cnt; i++) { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 304 | idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 305 | ch_h[i] = rx[idx].ch_h; |
| 306 | sph[i] = rx[idx].sph; |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 307 | slave_port_id = idx; |
| 308 | pr_debug("%s: idx %d, ch_h %d, sph %d\n", |
| 309 | __func__, idx, ch_h[i], sph[i]); |
| 310 | if ((slave_port_id > sh_ch.num_rx_slave_port)) { |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 311 | pr_err("Slimbus: invalid slave port id: %d", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 312 | slave_port_id); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 313 | ret = -EINVAL; |
| 314 | goto err; |
| 315 | } |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 316 | slave_port_id += sh_ch.rx_port_start_offset; |
| 317 | pr_debug("%s: slave_port_id %d\n", __func__, slave_port_id); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 318 | /* look for the valid port range and chose the |
| 319 | * payload accordingly |
| 320 | */ |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 321 | if ((slave_port_id > sh_ch.pgd_tx_port_ch_1_end_port_id) && |
| 322 | (slave_port_id <= sh_ch.port_ch_0_end_port_id)) { |
| 323 | payload_rx = payload_rx | |
| 324 | (1 << (slave_port_id - |
| 325 | sh_ch.port_ch_0_start_port_id)); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 326 | } else { |
| 327 | ret = -EINVAL; |
| 328 | goto err; |
| 329 | } |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 330 | |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 331 | multi_chan_cfg_reg_addr = |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 332 | SB_PGD_RX_PORT_MULTI_CHANNEL_0(sh_ch.rx_port_ch_reg_base, |
| 333 | idx); |
| 334 | pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\n", __func__, |
| 335 | multi_chan_cfg_reg_addr); |
| 336 | |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 337 | /* write to interface device */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 338 | ret = wcd9xxx_interface_reg_write(wcd9xxx, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 339 | multi_chan_cfg_reg_addr, |
| 340 | payload_rx); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 341 | if (ret < 0) { |
| 342 | pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 343 | __func__, multi_chan_cfg_reg_addr, |
| 344 | payload_rx, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 345 | goto err; |
| 346 | } |
| 347 | /* configure the slave port for water mark and enable*/ |
| 348 | wm_payload = (SLAVE_PORT_WATER_MARK_VALUE << |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 349 | SLAVE_PORT_WATER_MARK_SHIFT) + SLAVE_PORT_ENABLE; |
| 350 | ret = wcd9xxx_interface_reg_write( |
| 351 | wcd9xxx, |
| 352 | SB_PGD_PORT_CFG_BYTE_ADDR( |
| 353 | sh_ch.port_rx_cfg_reg_base, idx), |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 354 | wm_payload); |
| 355 | if (ret < 0) { |
| 356 | pr_err("%s:watermark set failure for port[%d] ret[%d]", |
| 357 | __func__, slave_port_id, ret); |
| 358 | } |
| 359 | } |
| 360 | |
| 361 | /* slim_define_ch api */ |
| 362 | prop.prot = SLIM_AUTO_ISO; |
| 363 | prop.baser = SLIM_RATE_4000HZ; |
| 364 | prop.dataf = SLIM_CH_DATAF_NOT_DEFINED; |
| 365 | prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE; |
| 366 | prop.ratem = (rate/4000); |
| 367 | prop.sampleszbits = 16; |
| 368 | |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 369 | ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt, true, &grph); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 370 | if (ret < 0) { |
| 371 | pr_err("%s: slim_define_ch failed ret[%d]\n", |
| 372 | __func__, ret); |
| 373 | goto err; |
| 374 | } |
| 375 | for (i = 0; i < ch_cnt; i++) { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 376 | ret = slim_connect_sink(wcd9xxx->slim, &sph[i], 1, ch_h[i]); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 377 | if (ret < 0) { |
| 378 | pr_err("%s: slim_connect_sink failed ret[%d]\n", |
| 379 | __func__, ret); |
| 380 | goto err_close_slim_sch; |
| 381 | } |
| 382 | } |
| 383 | /* slim_control_ch */ |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 384 | ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE, true); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 385 | if (ret < 0) { |
| 386 | pr_err("%s: slim_control_ch failed ret[%d]\n", |
| 387 | __func__, ret); |
| 388 | goto err_close_slim_sch; |
| 389 | } |
| 390 | for (i = 0; i < ch_cnt; i++) { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 391 | idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 392 | rx[idx].grph = grph; |
| 393 | } |
| 394 | return 0; |
| 395 | |
| 396 | err_close_slim_sch: |
| 397 | /* release all acquired handles */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 398 | wcd9xxx_close_slim_sch_rx(wcd9xxx, ch_num, ch_cnt); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 399 | err: |
| 400 | return ret; |
| 401 | } |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 402 | EXPORT_SYMBOL_GPL(wcd9xxx_cfg_slim_sch_rx); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 403 | |
| 404 | /* Enable slimbus slave device for RX path */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 405 | int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 406 | unsigned int ch_cnt, unsigned int rate) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 407 | { |
| 408 | u8 i = 0; |
| 409 | u8 payload_tx_0 = 0, payload_tx_1 = 0, wm_payload = 0; |
| 410 | u16 grph; |
| 411 | u32 sph[SLIM_MAX_TX_PORTS] = {0}; |
| 412 | u16 ch_h[SLIM_MAX_TX_PORTS] = {0}; |
| 413 | u16 idx = 0, slave_port_id; |
| 414 | int ret = 0; |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 415 | unsigned short multi_chan_cfg_reg_addr; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 416 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 417 | struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 418 | struct slim_ch prop; |
| 419 | |
| 420 | pr_debug("%s: ch_cnt[%d] rate[%d]\n", __func__, ch_cnt, rate); |
| 421 | for (i = 0; i < ch_cnt; i++) { |
| 422 | idx = (ch_num[i] - BASE_CH_NUM); |
| 423 | ch_h[i] = tx[idx].ch_h; |
| 424 | sph[i] = tx[idx].sph; |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 425 | slave_port_id = idx; |
| 426 | pr_debug("%s: idx %d, ch_h %d, sph %d, slave_port_id %d\n", |
| 427 | __func__, idx, ch_h[i], sph[i], slave_port_id); |
| 428 | if (slave_port_id > sh_ch.number_of_tx_slave_dev_ports) { |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 429 | pr_err("SLIMbus: invalid slave port id: %d", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 430 | slave_port_id); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 431 | ret = -EINVAL; |
| 432 | goto err; |
| 433 | } |
| 434 | /* look for the valid port range and chose the |
| 435 | * payload accordingly |
| 436 | */ |
| 437 | if (slave_port_id <= |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 438 | SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID) { |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 439 | payload_tx_0 = payload_tx_0 | (1 << slave_port_id); |
Kiran Kandi | 1e6371d | 2012-03-29 11:48:57 -0700 | [diff] [blame] | 440 | } else if (slave_port_id <= |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 441 | sh_ch.pgd_tx_port_ch_1_end_port_id) { |
| 442 | payload_tx_1 = payload_tx_1 | |
| 443 | (1 << (slave_port_id - |
| 444 | SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID)); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 445 | } else { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 446 | pr_err("%s: slave port id %d error\n", __func__, |
| 447 | slave_port_id); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 448 | ret = -EINVAL; |
| 449 | goto err; |
| 450 | } |
| 451 | multi_chan_cfg_reg_addr = |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 452 | SB_PGD_TX_PORT_MULTI_CHANNEL_0(slave_port_id); |
| 453 | pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\n", __func__, |
| 454 | multi_chan_cfg_reg_addr); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 455 | /* write to interface device */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 456 | ret = wcd9xxx_interface_reg_write(wcd9xxx, |
| 457 | multi_chan_cfg_reg_addr, |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 458 | payload_tx_0); |
| 459 | if (ret < 0) { |
| 460 | pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 461 | __func__, multi_chan_cfg_reg_addr, payload_tx_0, |
| 462 | ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 463 | goto err; |
| 464 | } |
| 465 | multi_chan_cfg_reg_addr = |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 466 | SB_PGD_TX_PORT_MULTI_CHANNEL_1(slave_port_id); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 467 | /* ports 8,9 */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 468 | ret = wcd9xxx_interface_reg_write(wcd9xxx, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 469 | multi_chan_cfg_reg_addr, |
| 470 | payload_tx_1); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 471 | if (ret < 0) { |
| 472 | pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 473 | __func__, multi_chan_cfg_reg_addr, |
| 474 | payload_tx_1, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 475 | goto err; |
| 476 | } |
| 477 | /* configure the slave port for water mark and enable*/ |
| 478 | wm_payload = (SLAVE_PORT_WATER_MARK_VALUE << |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 479 | SLAVE_PORT_WATER_MARK_SHIFT) + SLAVE_PORT_ENABLE; |
| 480 | pr_debug("%s: tx_cfg_reg 0x%x wm 0x%x\n", __func__, |
| 481 | SB_PGD_PORT_CFG_BYTE_ADDR(sh_ch.port_tx_cfg_reg_base, |
| 482 | slave_port_id), wm_payload); |
| 483 | ret = wcd9xxx_interface_reg_write( |
| 484 | wcd9xxx, |
| 485 | SB_PGD_PORT_CFG_BYTE_ADDR( |
| 486 | sh_ch.port_tx_cfg_reg_base, |
| 487 | slave_port_id), |
| 488 | wm_payload); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 489 | if (ret < 0) { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 490 | pr_err("%s: watermark set failure for port[%d] ret[%d]", |
| 491 | __func__, slave_port_id, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 492 | } |
| 493 | } |
| 494 | |
| 495 | /* slim_define_ch api */ |
| 496 | prop.prot = SLIM_AUTO_ISO; |
| 497 | prop.baser = SLIM_RATE_4000HZ; |
| 498 | prop.dataf = SLIM_CH_DATAF_NOT_DEFINED; |
| 499 | prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE; |
| 500 | prop.ratem = (rate/4000); |
| 501 | prop.sampleszbits = 16; |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 502 | ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt, true, &grph); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 503 | if (ret < 0) { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 504 | pr_err("%s: slim_define_ch failed ret[%d]\n", __func__, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 505 | goto err; |
| 506 | } |
| 507 | for (i = 0; i < ch_cnt; i++) { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 508 | ret = slim_connect_src(wcd9xxx->slim, sph[i], ch_h[i]); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 509 | if (ret < 0) { |
| 510 | pr_err("%s: slim_connect_src failed ret[%d]\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 511 | __func__, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 512 | goto err; |
| 513 | } |
| 514 | } |
| 515 | /* slim_control_ch */ |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 516 | ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE, true); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 517 | if (ret < 0) { |
| 518 | pr_err("%s: slim_control_ch failed ret[%d]\n", |
| 519 | __func__, ret); |
| 520 | goto err; |
| 521 | } |
| 522 | for (i = 0; i < ch_cnt; i++) { |
| 523 | idx = (ch_num[i] - BASE_CH_NUM); |
| 524 | tx[idx].grph = grph; |
| 525 | } |
| 526 | return 0; |
| 527 | err: |
| 528 | /* release all acquired handles */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 529 | wcd9xxx_close_slim_sch_tx(wcd9xxx, ch_num, ch_cnt); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 530 | return ret; |
| 531 | } |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 532 | EXPORT_SYMBOL_GPL(wcd9xxx_cfg_slim_sch_tx); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 533 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 534 | int wcd9xxx_close_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num, |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 535 | unsigned int ch_cnt) |
| 536 | { |
| 537 | u16 grph = 0; |
| 538 | u32 sph[SLIM_MAX_RX_PORTS] = {0}; |
| 539 | int i = 0 , idx = 0; |
| 540 | int ret = 0; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 541 | struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 542 | |
Swaminathan Sathappan | 362a17c | 2012-04-25 18:09:46 -0700 | [diff] [blame] | 543 | pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 544 | for (i = 0; i < ch_cnt; i++) { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 545 | idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset); |
Kiran Kandi | e408b84 | 2012-05-17 19:48:04 -0700 | [diff] [blame] | 546 | if (idx < 0) { |
| 547 | pr_err("%s: Error:-Invalid index found = %d\n", |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 548 | __func__, idx); |
Kiran Kandi | e408b84 | 2012-05-17 19:48:04 -0700 | [diff] [blame] | 549 | ret = -EINVAL; |
| 550 | goto err; |
| 551 | } |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 552 | sph[i] = rx[idx].sph; |
| 553 | grph = rx[idx].grph; |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 554 | pr_debug("%s: ch_num[%d] %d, idx %d, sph[%d] %x, grph %x\n", |
| 555 | __func__, i, ch_num[i], idx, i, sph[i], grph); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 556 | } |
| 557 | |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 558 | /* slim_control_ch (REMOVE) */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 559 | ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 560 | if (ret < 0) { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 561 | pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 562 | goto err; |
| 563 | } |
Swaminathan Sathappan | cb89d7d | 2012-08-01 13:20:20 -0700 | [diff] [blame] | 564 | /* slim_disconnect_port */ |
| 565 | ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt); |
| 566 | if (ret < 0) { |
| 567 | pr_err("%s: slim_disconnect_ports failed ret[%d]\n", |
| 568 | __func__, ret); |
| 569 | } |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 570 | for (i = 0; i < ch_cnt; i++) { |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 571 | idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 572 | rx[idx].grph = 0; |
| 573 | } |
| 574 | err: |
| 575 | return ret; |
| 576 | } |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 577 | EXPORT_SYMBOL_GPL(wcd9xxx_close_slim_sch_rx); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 578 | |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 579 | int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num, |
Joonwoo Park | a717211 | 2012-07-23 16:03:49 -0700 | [diff] [blame] | 580 | unsigned int ch_cnt) |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 581 | { |
| 582 | u16 grph = 0; |
| 583 | u32 sph[SLIM_MAX_TX_PORTS] = {0}; |
| 584 | int ret = 0; |
| 585 | int i = 0 , idx = 0; |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 586 | struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx; |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 587 | |
Swaminathan Sathappan | 362a17c | 2012-04-25 18:09:46 -0700 | [diff] [blame] | 588 | pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 589 | for (i = 0; i < ch_cnt; i++) { |
| 590 | idx = (ch_num[i] - BASE_CH_NUM); |
Kiran Kandi | e408b84 | 2012-05-17 19:48:04 -0700 | [diff] [blame] | 591 | if (idx < 0) { |
| 592 | pr_err("%s: Error:- Invalid index found = %d\n", |
| 593 | __func__, idx); |
| 594 | ret = -EINVAL; |
| 595 | goto err; |
| 596 | } |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 597 | sph[i] = tx[idx].sph; |
| 598 | grph = tx[idx].grph; |
| 599 | } |
Jay Wang | a19be7b | 2012-06-15 18:29:33 -0700 | [diff] [blame] | 600 | /* slim_disconnect_port */ |
| 601 | ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt); |
| 602 | if (ret < 0) { |
| 603 | pr_err("%s: slim_disconnect_ports failed ret[%d]\n", |
| 604 | __func__, ret); |
| 605 | } |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 606 | /* slim_control_ch (REMOVE) */ |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 607 | ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true); |
Bharath Ramachandramurthy | 9c79f13 | 2011-11-28 11:18:57 -0800 | [diff] [blame] | 608 | if (ret < 0) { |
| 609 | pr_err("%s: slim_control_ch failed ret[%d]\n", |
| 610 | __func__, ret); |
| 611 | goto err; |
| 612 | } |
| 613 | for (i = 0; i < ch_cnt; i++) { |
| 614 | idx = (ch_num[i] - BASE_CH_NUM); |
| 615 | tx[idx].grph = 0; |
| 616 | } |
| 617 | err: |
| 618 | return ret; |
| 619 | } |
Asish Bhattacharya | b1aeae2 | 2012-02-15 08:29:28 +0530 | [diff] [blame] | 620 | EXPORT_SYMBOL_GPL(wcd9xxx_close_slim_sch_tx); |
Swaminathan Sathappan | 2aa4c04 | 2012-06-26 13:08:45 -0700 | [diff] [blame] | 621 | |
| 622 | int wcd9xxx_get_slave_port(unsigned int ch_num) |
| 623 | { |
| 624 | int ret = 0; |
| 625 | |
| 626 | pr_debug("%s: ch_num[%d]\n", __func__, ch_num); |
| 627 | ret = (ch_num - BASE_CH_NUM); |
| 628 | if (ret < 0) { |
| 629 | pr_err("%s: Error:- Invalid slave port found = %d\n", |
| 630 | __func__, ret); |
| 631 | return -EINVAL; |
| 632 | } |
| 633 | return ret; |
| 634 | } |
| 635 | EXPORT_SYMBOL_GPL(wcd9xxx_get_slave_port); |