Lines Matching +full:num +full:- +full:ports
1 // SPDX-License-Identifier: GPL-2.0-only
2 // cs42l42-sdw.c -- CS42L42 ALSA SoC audio driver SoundWire driver
55 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component); in cs42l42_sdw_dai_startup()
57 if (!cs42l42->init_done) in cs42l42_sdw_dai_startup()
58 return -ENODEV; in cs42l42_sdw_dai_startup()
67 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component); in cs42l42_sdw_dai_hw_params()
74 return -EINVAL; in cs42l42_sdw_dai_hw_params()
77 cs42l42->sample_rate = params_rate(params); in cs42l42_sdw_dai_hw_params()
81 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in cs42l42_sdw_dai_hw_params()
82 port_config.num = CS42L42_SDW_PLAYBACK_PORT; in cs42l42_sdw_dai_hw_params()
84 port_config.num = CS42L42_SDW_CAPTURE_PORT; in cs42l42_sdw_dai_hw_params()
86 ret = sdw_stream_add_slave(cs42l42->sdw_peripheral, &stream_config, &port_config, 1, in cs42l42_sdw_dai_hw_params()
89 dev_err(dai->dev, "Failed to add sdw stream: %d\n", ret); in cs42l42_sdw_dai_hw_params()
93 cs42l42_src_config(dai->component, params_rate(params)); in cs42l42_sdw_dai_hw_params()
101 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component); in cs42l42_sdw_dai_prepare()
103 dev_dbg(dai->dev, "dai_prepare: sclk=%u rate=%u\n", cs42l42->sclk, cs42l42->sample_rate); in cs42l42_sdw_dai_prepare()
105 if (!cs42l42->sclk || !cs42l42->sample_rate) in cs42l42_sdw_dai_prepare()
106 return -EINVAL; in cs42l42_sdw_dai_prepare()
114 return cs42l42_pll_config(dai->component, cs42l42->sclk, cs42l42->sample_rate); in cs42l42_sdw_dai_prepare()
120 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component); in cs42l42_sdw_dai_hw_free()
123 sdw_stream_remove_slave(cs42l42->sdw_peripheral, sdw_stream); in cs42l42_sdw_dai_hw_free()
124 cs42l42->sample_rate = 0; in cs42l42_sdw_dai_hw_free()
133 struct cs42l42_private *cs42l42 = dev_get_drvdata(&slave->dev); in cs42l42_sdw_port_prep()
136 if (prepare_ch->num == CS42L42_SDW_PLAYBACK_PORT) in cs42l42_sdw_port_prep()
142 dev_dbg(cs42l42->dev, "Prep Port pdn_mask:%x\n", pdn_mask); in cs42l42_sdw_port_prep()
143 regmap_clear_bits(cs42l42->regmap, CS42L42_PWR_CTL1, pdn_mask); in cs42l42_sdw_port_prep()
146 dev_dbg(cs42l42->dev, "Deprep Port pdn_mask:%x\n", pdn_mask); in cs42l42_sdw_port_prep()
147 regmap_set_bits(cs42l42->regmap, CS42L42_PWR_CTL1, pdn_mask); in cs42l42_sdw_port_prep()
178 .name = "cs42l42-sdw",
215 dev_err(&peripheral->dev, "MEM_ACCESS_STATUS & %#x for %#x fail: %d\n", in cs42l42_sdw_poll_status()
235 dev_err(&peripheral->dev, "Failed to issue read @0x%x: %d\n", reg, ret); in cs42l42_sdw_read()
239 data = (u8)ret; /* possible non-delayed read value */ in cs42l42_sdw_read()
242 dev_err(&peripheral->dev, "Failed to read MEM_ACCESS_STATUS: %d\n", ret); in cs42l42_sdw_read()
262 dev_err(&peripheral->dev, "Failed to read READ_DATA: %d\n", ret); in cs42l42_sdw_read()
283 /* Initialise cs42l42 using SoundWire - this is only called once, during initialisation */
286 struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); in cs42l42_sdw_init()
289 regcache_cache_only(cs42l42->regmap, false); in cs42l42_sdw_init()
293 regcache_cache_only(cs42l42->regmap, true); in cs42l42_sdw_init()
298 ret = regcache_sync(cs42l42->regmap); in cs42l42_sdw_init()
300 dev_warn(cs42l42->dev, "Failed to sync cache: %d\n", ret); in cs42l42_sdw_init()
302 /* Disable internal logic that makes clock-stop conditional */ in cs42l42_sdw_init()
303 regmap_clear_bits(cs42l42->regmap, CS42L42_PWR_CTL3, CS42L42_SW_CLK_STP_STAT_SEL_MASK); in cs42l42_sdw_init()
307 pm_runtime_put_autosuspend(cs42l42->dev); in cs42l42_sdw_init()
312 struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); in cs42l42_sdw_read_prop()
313 struct sdw_slave_prop *prop = &peripheral->prop; in cs42l42_sdw_read_prop()
314 struct sdw_dpn_prop *ports; in cs42l42_sdw_read_prop() local
316 ports = devm_kcalloc(cs42l42->dev, 2, sizeof(*ports), GFP_KERNEL); in cs42l42_sdw_read_prop()
317 if (!ports) in cs42l42_sdw_read_prop()
318 return -ENOMEM; in cs42l42_sdw_read_prop()
320 prop->source_ports = BIT(CS42L42_SDW_CAPTURE_PORT); in cs42l42_sdw_read_prop()
321 prop->sink_ports = BIT(CS42L42_SDW_PLAYBACK_PORT); in cs42l42_sdw_read_prop()
322 prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; in cs42l42_sdw_read_prop()
323 prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; in cs42l42_sdw_read_prop()
325 /* DP1 - capture */ in cs42l42_sdw_read_prop()
326 ports[0].num = CS42L42_SDW_CAPTURE_PORT, in cs42l42_sdw_read_prop()
327 ports[0].type = SDW_DPN_FULL, in cs42l42_sdw_read_prop()
328 ports[0].ch_prep_timeout = 10, in cs42l42_sdw_read_prop()
329 prop->src_dpn_prop = &ports[0]; in cs42l42_sdw_read_prop()
331 /* DP2 - playback */ in cs42l42_sdw_read_prop()
332 ports[1].num = CS42L42_SDW_PLAYBACK_PORT, in cs42l42_sdw_read_prop()
333 ports[1].type = SDW_DPN_FULL, in cs42l42_sdw_read_prop()
334 ports[1].ch_prep_timeout = 10, in cs42l42_sdw_read_prop()
335 prop->sink_dpn_prop = &ports[1]; in cs42l42_sdw_read_prop()
343 struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); in cs42l42_sdw_update_status()
347 dev_dbg(cs42l42->dev, "ATTACHED\n"); in cs42l42_sdw_update_status()
351 * if we hard-reset CS42L42 in probe() but it had already been in cs42l42_sdw_update_status()
355 if (cs42l42->sdw_waiting_first_unattach) in cs42l42_sdw_update_status()
360 * When resuming from suspend, resume callback will handle re-init of codec, in cs42l42_sdw_update_status()
363 if (!cs42l42->init_done) in cs42l42_sdw_update_status()
367 dev_dbg(cs42l42->dev, "UNATTACHED\n"); in cs42l42_sdw_update_status()
369 if (cs42l42->sdw_waiting_first_unattach) { in cs42l42_sdw_update_status()
374 cs42l42->sdw_waiting_first_unattach = false; in cs42l42_sdw_update_status()
375 gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); in cs42l42_sdw_update_status()
389 struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); in cs42l42_sdw_bus_config()
390 unsigned int new_sclk = params->curr_dr_freq / 2; in cs42l42_sdw_bus_config()
393 if ((new_sclk != cs42l42->sclk) && cs42l42->stream_use) { in cs42l42_sdw_bus_config()
394 dev_warn(cs42l42->dev, "Rejected SCLK change while audio active\n"); in cs42l42_sdw_bus_config()
395 return -EBUSY; in cs42l42_sdw_bus_config()
398 cs42l42->sclk = new_sclk; in cs42l42_sdw_bus_config()
400 dev_dbg(cs42l42->dev, "bus_config: sclk=%u c=%u r=%u\n", in cs42l42_sdw_bus_config()
401 cs42l42->sclk, params->col, params->row); in cs42l42_sdw_bus_config()
420 if (!cs42l42->init_done) in cs42l42_sdw_runtime_suspend()
424 regcache_cache_only(cs42l42->regmap, true); in cs42l42_sdw_runtime_suspend()
435 struct sdw_slave *peripheral = cs42l42->sdw_peripheral; in cs42l42_sdw_handle_unattach()
437 if (!peripheral->unattach_request) in cs42l42_sdw_handle_unattach()
440 /* Cannot access registers until master re-attaches. */ in cs42l42_sdw_handle_unattach()
441 dev_dbg(&peripheral->dev, "Wait for initialization_complete\n"); in cs42l42_sdw_handle_unattach()
442 if (!wait_for_completion_timeout(&peripheral->initialization_complete, in cs42l42_sdw_handle_unattach()
444 dev_err(&peripheral->dev, "initialization_complete timed out\n"); in cs42l42_sdw_handle_unattach()
445 return -ETIMEDOUT; in cs42l42_sdw_handle_unattach()
448 peripheral->unattach_request = 0; in cs42l42_sdw_handle_unattach()
454 regmap_multi_reg_write_bypassed(cs42l42->regmap, in cs42l42_sdw_handle_unattach()
458 regcache_mark_dirty(cs42l42->regmap); in cs42l42_sdw_handle_unattach()
472 if (!cs42l42->init_done) in cs42l42_sdw_runtime_resume()
479 dbnce = max(cs42l42->ts_dbnc_rise, cs42l42->ts_dbnc_fall); in cs42l42_sdw_runtime_resume()
485 regcache_cache_only(cs42l42->regmap, false); in cs42l42_sdw_runtime_resume()
488 regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1); in cs42l42_sdw_runtime_resume()
489 regcache_sync(cs42l42->regmap); in cs42l42_sdw_runtime_resume()
501 /* Power-up so it can re-enumerate */ in cs42l42_sdw_resume()
506 /* Wait for re-attach */ in cs42l42_sdw_resume()
519 struct device *dev = &peripheral->dev; in cs42l42_sdw_probe()
527 return -ENOMEM; in cs42l42_sdw_probe()
532 irq = of_irq_get(dev->of_node, 0); in cs42l42_sdw_probe()
534 if (irq == -ENOENT) in cs42l42_sdw_probe()
541 return -ENOMEM; in cs42l42_sdw_probe()
542 regmap_conf->reg_bits = 16; in cs42l42_sdw_probe()
543 regmap_conf->num_ranges = 0; in cs42l42_sdw_probe()
544 regmap_conf->reg_read = cs42l42_sdw_read; in cs42l42_sdw_probe()
545 regmap_conf->reg_write = cs42l42_sdw_write; in cs42l42_sdw_probe()
551 /* Start in cache-only until device is enumerated */ in cs42l42_sdw_probe()
559 return -ENOMEM; in cs42l42_sdw_probe()
561 component_drv->dapm_routes = cs42l42_sdw_audio_map; in cs42l42_sdw_probe()
562 component_drv->num_dapm_routes = ARRAY_SIZE(cs42l42_sdw_audio_map); in cs42l42_sdw_probe()
564 cs42l42->dev = dev; in cs42l42_sdw_probe()
565 cs42l42->regmap = regmap; in cs42l42_sdw_probe()
566 cs42l42->sdw_peripheral = peripheral; in cs42l42_sdw_probe()
567 cs42l42->irq = irq; in cs42l42_sdw_probe()
568 cs42l42->devid = CS42L42_CHIP_ID; in cs42l42_sdw_probe()
574 pm_runtime_set_autosuspend_delay(cs42l42->dev, 3000); in cs42l42_sdw_probe()
575 pm_runtime_use_autosuspend(cs42l42->dev); in cs42l42_sdw_probe()
576 pm_runtime_mark_last_busy(cs42l42->dev); in cs42l42_sdw_probe()
577 pm_runtime_set_active(cs42l42->dev); in cs42l42_sdw_probe()
578 pm_runtime_get_noresume(cs42l42->dev); in cs42l42_sdw_probe()
579 pm_runtime_enable(cs42l42->dev); in cs42l42_sdw_probe()
590 struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); in cs42l42_sdw_remove()
593 pm_runtime_disable(cs42l42->dev); in cs42l42_sdw_remove()
611 .name = "cs42l42-sdw",