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