1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2021, Linaro Limited 3 4 #include <linux/module.h> 5 #include <linux/slab.h> 6 #include <linux/platform_device.h> 7 #include <linux/device.h> 8 #include <linux/kernel.h> 9 #include <linux/component.h> 10 #include <sound/soc.h> 11 #include <linux/pm_runtime.h> 12 #include <linux/irqdomain.h> 13 #include <linux/of.h> 14 #include <linux/soundwire/sdw.h> 15 #include <linux/soundwire/sdw_type.h> 16 #include <linux/soundwire/sdw_registers.h> 17 #include <linux/regmap.h> 18 #include <sound/soc.h> 19 #include <sound/soc-dapm.h> 20 #include "wcd938x.h" 21 22 #define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (0xE0 + 0x10 * (m)) 23 24 static struct wcd938x_sdw_ch_info wcd938x_sdw_rx_ch_info[] = { 25 WCD_SDW_CH(WCD938X_HPH_L, WCD938X_HPH_PORT, BIT(0)), 26 WCD_SDW_CH(WCD938X_HPH_R, WCD938X_HPH_PORT, BIT(1)), 27 WCD_SDW_CH(WCD938X_CLSH, WCD938X_CLSH_PORT, BIT(0)), 28 WCD_SDW_CH(WCD938X_COMP_L, WCD938X_COMP_PORT, BIT(0)), 29 WCD_SDW_CH(WCD938X_COMP_R, WCD938X_COMP_PORT, BIT(1)), 30 WCD_SDW_CH(WCD938X_LO, WCD938X_LO_PORT, BIT(0)), 31 WCD_SDW_CH(WCD938X_DSD_L, WCD938X_DSD_PORT, BIT(0)), 32 WCD_SDW_CH(WCD938X_DSD_R, WCD938X_DSD_PORT, BIT(1)), 33 }; 34 35 static struct wcd938x_sdw_ch_info wcd938x_sdw_tx_ch_info[] = { 36 WCD_SDW_CH(WCD938X_ADC1, WCD938X_ADC_1_2_PORT, BIT(0)), 37 WCD_SDW_CH(WCD938X_ADC2, WCD938X_ADC_1_2_PORT, BIT(1)), 38 WCD_SDW_CH(WCD938X_ADC3, WCD938X_ADC_3_4_PORT, BIT(0)), 39 WCD_SDW_CH(WCD938X_ADC4, WCD938X_ADC_3_4_PORT, BIT(1)), 40 WCD_SDW_CH(WCD938X_DMIC0, WCD938X_DMIC_0_3_MBHC_PORT, BIT(0)), 41 WCD_SDW_CH(WCD938X_DMIC1, WCD938X_DMIC_0_3_MBHC_PORT, BIT(1)), 42 WCD_SDW_CH(WCD938X_MBHC, WCD938X_DMIC_0_3_MBHC_PORT, BIT(2)), 43 WCD_SDW_CH(WCD938X_DMIC2, WCD938X_DMIC_0_3_MBHC_PORT, BIT(2)), 44 WCD_SDW_CH(WCD938X_DMIC3, WCD938X_DMIC_0_3_MBHC_PORT, BIT(3)), 45 WCD_SDW_CH(WCD938X_DMIC4, WCD938X_DMIC_4_7_PORT, BIT(0)), 46 WCD_SDW_CH(WCD938X_DMIC5, WCD938X_DMIC_4_7_PORT, BIT(1)), 47 WCD_SDW_CH(WCD938X_DMIC6, WCD938X_DMIC_4_7_PORT, BIT(2)), 48 WCD_SDW_CH(WCD938X_DMIC7, WCD938X_DMIC_4_7_PORT, BIT(3)), 49 }; 50 51 static struct sdw_dpn_prop wcd938x_dpn_prop[WCD938X_MAX_SWR_PORTS] = { 52 { 53 .num = 1, 54 .type = SDW_DPN_SIMPLE, 55 .min_ch = 1, 56 .max_ch = 8, 57 .simple_ch_prep_sm = true, 58 }, { 59 .num = 2, 60 .type = SDW_DPN_SIMPLE, 61 .min_ch = 1, 62 .max_ch = 4, 63 .simple_ch_prep_sm = true, 64 }, { 65 .num = 3, 66 .type = SDW_DPN_SIMPLE, 67 .min_ch = 1, 68 .max_ch = 4, 69 .simple_ch_prep_sm = true, 70 }, { 71 .num = 4, 72 .type = SDW_DPN_SIMPLE, 73 .min_ch = 1, 74 .max_ch = 4, 75 .simple_ch_prep_sm = true, 76 }, { 77 .num = 5, 78 .type = SDW_DPN_SIMPLE, 79 .min_ch = 1, 80 .max_ch = 4, 81 .simple_ch_prep_sm = true, 82 } 83 }; 84 85 struct device *wcd938x_sdw_device_get(struct device_node *np) 86 { 87 return bus_find_device_by_of_node(&sdw_bus_type, np); 88 89 } 90 EXPORT_SYMBOL_GPL(wcd938x_sdw_device_get); 91 92 int wcd938x_swr_get_current_bank(struct sdw_slave *sdev) 93 { 94 int bank; 95 96 bank = sdw_read(sdev, SDW_SCP_CTRL); 97 98 return ((bank & 0x40) ? 1 : 0); 99 } 100 EXPORT_SYMBOL_GPL(wcd938x_swr_get_current_bank); 101 102 int wcd938x_sdw_hw_params(struct wcd938x_sdw_priv *wcd, 103 struct snd_pcm_substream *substream, 104 struct snd_pcm_hw_params *params, 105 struct snd_soc_dai *dai) 106 { 107 struct sdw_port_config port_config[WCD938X_MAX_SWR_PORTS]; 108 unsigned long ch_mask; 109 int i, j; 110 111 wcd->sconfig.ch_count = 1; 112 wcd->active_ports = 0; 113 for (i = 0; i < WCD938X_MAX_SWR_PORTS; i++) { 114 ch_mask = wcd->port_config[i].ch_mask; 115 116 if (!ch_mask) 117 continue; 118 119 for_each_set_bit(j, &ch_mask, 4) 120 wcd->sconfig.ch_count++; 121 122 port_config[wcd->active_ports] = wcd->port_config[i]; 123 wcd->active_ports++; 124 } 125 126 wcd->sconfig.bps = 1; 127 wcd->sconfig.frame_rate = params_rate(params); 128 if (wcd->is_tx) 129 wcd->sconfig.direction = SDW_DATA_DIR_TX; 130 else 131 wcd->sconfig.direction = SDW_DATA_DIR_RX; 132 133 wcd->sconfig.type = SDW_STREAM_PCM; 134 135 return sdw_stream_add_slave(wcd->sdev, &wcd->sconfig, 136 &port_config[0], wcd->active_ports, 137 wcd->sruntime); 138 } 139 EXPORT_SYMBOL_GPL(wcd938x_sdw_hw_params); 140 141 int wcd938x_sdw_free(struct wcd938x_sdw_priv *wcd, 142 struct snd_pcm_substream *substream, 143 struct snd_soc_dai *dai) 144 { 145 sdw_stream_remove_slave(wcd->sdev, wcd->sruntime); 146 147 return 0; 148 } 149 EXPORT_SYMBOL_GPL(wcd938x_sdw_free); 150 151 int wcd938x_sdw_set_sdw_stream(struct wcd938x_sdw_priv *wcd, 152 struct snd_soc_dai *dai, 153 void *stream, int direction) 154 { 155 wcd->sruntime = stream; 156 157 return 0; 158 } 159 EXPORT_SYMBOL_GPL(wcd938x_sdw_set_sdw_stream); 160 161 static int wcd9380_update_status(struct sdw_slave *slave, 162 enum sdw_slave_status status) 163 { 164 return 0; 165 } 166 167 static int wcd9380_bus_config(struct sdw_slave *slave, 168 struct sdw_bus_params *params) 169 { 170 sdw_write(slave, SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(params->next_bank), 0x01); 171 172 return 0; 173 } 174 175 static int wcd9380_interrupt_callback(struct sdw_slave *slave, 176 struct sdw_slave_intr_status *status) 177 { 178 struct wcd938x_sdw_priv *wcd = dev_get_drvdata(&slave->dev); 179 180 return wcd938x_handle_sdw_irq(wcd); 181 } 182 183 static struct sdw_slave_ops wcd9380_slave_ops = { 184 .update_status = wcd9380_update_status, 185 .interrupt_callback = wcd9380_interrupt_callback, 186 .bus_config = wcd9380_bus_config, 187 }; 188 189 static int wcd938x_sdw_component_bind(struct device *dev, 190 struct device *master, void *data) 191 { 192 return 0; 193 } 194 195 static void wcd938x_sdw_component_unbind(struct device *dev, 196 struct device *master, void *data) 197 { 198 } 199 200 static const struct component_ops wcd938x_sdw_component_ops = { 201 .bind = wcd938x_sdw_component_bind, 202 .unbind = wcd938x_sdw_component_unbind, 203 }; 204 205 static int wcd9380_probe(struct sdw_slave *pdev, 206 const struct sdw_device_id *id) 207 { 208 struct device *dev = &pdev->dev; 209 struct wcd938x_sdw_priv *wcd; 210 int ret; 211 212 wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL); 213 if (!wcd) 214 return -ENOMEM; 215 216 /** 217 * Port map index starts with 0, however the data port for this codec 218 * are from index 1 219 */ 220 if (of_property_read_bool(dev->of_node, "qcom,tx-port-mapping")) { 221 wcd->is_tx = true; 222 ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping", 223 &pdev->m_port_map[1], 224 WCD938X_MAX_TX_SWR_PORTS); 225 } else { 226 ret = of_property_read_u32_array(dev->of_node, "qcom,rx-port-mapping", 227 &pdev->m_port_map[1], 228 WCD938X_MAX_SWR_PORTS); 229 } 230 231 if (ret < 0) 232 dev_info(dev, "Static Port mapping not specified\n"); 233 234 wcd->sdev = pdev; 235 dev_set_drvdata(dev, wcd); 236 237 pdev->prop.scp_int1_mask = SDW_SCP_INT1_IMPL_DEF | 238 SDW_SCP_INT1_BUS_CLASH | 239 SDW_SCP_INT1_PARITY; 240 pdev->prop.lane_control_support = true; 241 if (wcd->is_tx) { 242 struct regmap *rm; 243 244 pdev->prop.source_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0); 245 pdev->prop.src_dpn_prop = wcd938x_dpn_prop; 246 wcd->ch_info = &wcd938x_sdw_tx_ch_info[0]; 247 pdev->prop.wake_capable = true; 248 249 rm = devm_regmap_init_sdw(pdev, &wcd938x_regmap_config); 250 if (IS_ERR(rm)) 251 return PTR_ERR(rm); 252 } else { 253 pdev->prop.sink_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0); 254 pdev->prop.sink_dpn_prop = wcd938x_dpn_prop; 255 wcd->ch_info = &wcd938x_sdw_rx_ch_info[0]; 256 } 257 258 pm_runtime_set_autosuspend_delay(dev, 3000); 259 pm_runtime_use_autosuspend(dev); 260 pm_runtime_mark_last_busy(dev); 261 pm_runtime_set_active(dev); 262 pm_runtime_enable(dev); 263 264 return component_add(dev, &wcd938x_sdw_component_ops); 265 } 266 267 static const struct sdw_device_id wcd9380_slave_id[] = { 268 SDW_SLAVE_ENTRY(0x0217, 0x10d, 0), 269 {}, 270 }; 271 MODULE_DEVICE_TABLE(sdw, wcd9380_slave_id); 272 273 static int __maybe_unused wcd938x_sdw_runtime_suspend(struct device *dev) 274 { 275 struct regmap *regmap = dev_get_regmap(dev, NULL); 276 277 if (regmap) { 278 regcache_cache_only(regmap, true); 279 regcache_mark_dirty(regmap); 280 } 281 return 0; 282 } 283 284 static int __maybe_unused wcd938x_sdw_runtime_resume(struct device *dev) 285 { 286 struct regmap *regmap = dev_get_regmap(dev, NULL); 287 288 if (regmap) { 289 regcache_cache_only(regmap, false); 290 regcache_sync(regmap); 291 } 292 293 pm_runtime_mark_last_busy(dev); 294 295 return 0; 296 } 297 298 static const struct dev_pm_ops wcd938x_sdw_pm_ops = { 299 SET_RUNTIME_PM_OPS(wcd938x_sdw_runtime_suspend, wcd938x_sdw_runtime_resume, NULL) 300 }; 301 302 303 static struct sdw_driver wcd9380_codec_driver = { 304 .probe = wcd9380_probe, 305 .ops = &wcd9380_slave_ops, 306 .id_table = wcd9380_slave_id, 307 .driver = { 308 .name = "wcd9380-codec", 309 .pm = &wcd938x_sdw_pm_ops, 310 } 311 }; 312 module_sdw_driver(wcd9380_codec_driver); 313 314 MODULE_DESCRIPTION("WCD938X SDW codec driver"); 315 MODULE_LICENSE("GPL"); 316