Lines Matching +full:autosuspend +full:- +full:delay
1 // SPDX-License-Identifier: GPL-2.0
3 // rt1308-sdw.c -- rt1308 ALSA SoC audio driver
8 #include <linux/delay.h>
22 #include <sound/soc-dapm.h>
26 #include "rt1308-sdw.h"
90 clk_freq = (rt1308->params.curr_dr_freq >> 1); in rt1308_clock_config()
112 return -EINVAL; in rt1308_clock_config()
115 regmap_write(rt1308->regmap, 0xe0, value); in rt1308_clock_config()
116 regmap_write(rt1308->regmap, 0xf0, value); in rt1308_clock_config()
125 struct sdw_slave_prop *prop = &slave->prop; in rt1308_read_prop()
131 prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; in rt1308_read_prop()
132 prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; in rt1308_read_prop()
134 prop->paging_support = true; in rt1308_read_prop()
137 prop->source_ports = 0x00; /* BITMAP: 00010100 (not enable yet) */ in rt1308_read_prop()
138 prop->sink_ports = 0x2; /* BITMAP: 00000010 */ in rt1308_read_prop()
141 nval = hweight32(prop->sink_ports); in rt1308_read_prop()
142 prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval, in rt1308_read_prop()
143 sizeof(*prop->sink_dpn_prop), in rt1308_read_prop()
145 if (!prop->sink_dpn_prop) in rt1308_read_prop()
146 return -ENOMEM; in rt1308_read_prop()
149 dpn = prop->sink_dpn_prop; in rt1308_read_prop()
150 addr = prop->sink_ports; in rt1308_read_prop()
160 prop->clk_stop_timeout = 20; in rt1308_read_prop()
162 dev_dbg(&slave->dev, "%s\n", __func__); in rt1308_read_prop()
173 regmap_write(rt1308->regmap, 0xc7f0, 0x04); in rt1308_apply_calib_params()
174 regmap_write(rt1308->regmap, 0xc7f1, 0xfe); in rt1308_apply_calib_params()
176 regmap_write(rt1308->regmap, 0xc7f0, 0x44); in rt1308_apply_calib_params()
178 regmap_write(rt1308->regmap, 0xc240, 0x10); in rt1308_apply_calib_params()
180 regmap_read(rt1308->regmap, 0xc861, &tmp); in rt1308_apply_calib_params()
182 regmap_read(rt1308->regmap, 0xc860, &tmp); in rt1308_apply_calib_params()
184 regmap_read(rt1308->regmap, 0xc863, &tmp); in rt1308_apply_calib_params()
186 regmap_read(rt1308->regmap, 0xc862, &tmp); in rt1308_apply_calib_params()
188 regmap_read(rt1308->regmap, 0xc871, &tmp); in rt1308_apply_calib_params()
190 regmap_read(rt1308->regmap, 0xc870, &tmp); in rt1308_apply_calib_params()
192 regmap_read(rt1308->regmap, 0xc873, &tmp); in rt1308_apply_calib_params()
194 regmap_read(rt1308->regmap, 0xc872, &tmp); in rt1308_apply_calib_params()
196 dev_dbg(&rt1308->sdw_slave->dev, "%s m_btl_l=0x%x, m_btl_r=0x%x\n", __func__, in rt1308_apply_calib_params()
198 dev_dbg(&rt1308->sdw_slave->dev, "%s c_btl_l=0x%x, c_btl_r=0x%x\n", __func__, in rt1308_apply_calib_params()
206 for (i = 0; i < rt1308->bq_params_cnt; i += 3) { in rt1308_apply_bq_params()
207 reg = rt1308->bq_params[i] | (rt1308->bq_params[i + 1] << 8); in rt1308_apply_bq_params()
208 data = rt1308->bq_params[i + 2]; in rt1308_apply_bq_params()
209 regmap_write(rt1308->regmap, reg, data); in rt1308_apply_bq_params()
219 if (rt1308->hw_init) in rt1308_io_init()
222 regcache_cache_only(rt1308->regmap, false); in rt1308_io_init()
223 if (rt1308->first_hw_init) in rt1308_io_init()
224 regcache_cache_bypass(rt1308->regmap, true); in rt1308_io_init()
229 if (!rt1308->first_hw_init) in rt1308_io_init()
231 pm_runtime_set_active(&slave->dev); in rt1308_io_init()
233 pm_runtime_get_noresume(&slave->dev); in rt1308_io_init()
235 regmap_read(rt1308->regmap, 0xcf01, &hibernation_flag); in rt1308_io_init()
236 if ((hibernation_flag != 0x00) && rt1308->first_hw_init) in rt1308_io_init()
240 regmap_write(rt1308->regmap, RT1308_SDW_RESET, 0); in rt1308_io_init()
242 regmap_read(rt1308->regmap, 0xc710, &tmp); in rt1308_io_init()
243 rt1308->hw_ver = tmp; in rt1308_io_init()
244 dev_dbg(dev, "%s, hw_ver=0x%x\n", __func__, rt1308->hw_ver); in rt1308_io_init()
247 regmap_write(rt1308->regmap, 0xc103, 0xc0); in rt1308_io_init()
248 regmap_write(rt1308->regmap, 0xc030, 0x17); in rt1308_io_init()
249 regmap_write(rt1308->regmap, 0xc031, 0x81); in rt1308_io_init()
250 regmap_write(rt1308->regmap, 0xc032, 0x26); in rt1308_io_init()
251 regmap_write(rt1308->regmap, 0xc040, 0x80); in rt1308_io_init()
252 regmap_write(rt1308->regmap, 0xc041, 0x80); in rt1308_io_init()
253 regmap_write(rt1308->regmap, 0xc042, 0x06); in rt1308_io_init()
254 regmap_write(rt1308->regmap, 0xc052, 0x0a); in rt1308_io_init()
255 regmap_write(rt1308->regmap, 0xc080, 0x0a); in rt1308_io_init()
256 regmap_write(rt1308->regmap, 0xc060, 0x02); in rt1308_io_init()
257 regmap_write(rt1308->regmap, 0xc061, 0x75); in rt1308_io_init()
258 regmap_write(rt1308->regmap, 0xc062, 0x05); in rt1308_io_init()
259 regmap_write(rt1308->regmap, 0xc171, 0x07); in rt1308_io_init()
260 regmap_write(rt1308->regmap, 0xc173, 0x0d); in rt1308_io_init()
261 if (rt1308->hw_ver == RT1308_VER_C) { in rt1308_io_init()
262 regmap_write(rt1308->regmap, 0xc311, 0x7f); in rt1308_io_init()
263 regmap_write(rt1308->regmap, 0xc300, 0x09); in rt1308_io_init()
265 regmap_write(rt1308->regmap, 0xc311, 0x4f); in rt1308_io_init()
266 regmap_write(rt1308->regmap, 0xc300, 0x0b); in rt1308_io_init()
268 regmap_write(rt1308->regmap, 0xc900, 0x5a); in rt1308_io_init()
269 regmap_write(rt1308->regmap, 0xc1a0, 0x84); in rt1308_io_init()
270 regmap_write(rt1308->regmap, 0xc1a1, 0x01); in rt1308_io_init()
271 regmap_write(rt1308->regmap, 0xc360, 0x78); in rt1308_io_init()
272 regmap_write(rt1308->regmap, 0xc361, 0x87); in rt1308_io_init()
273 regmap_write(rt1308->regmap, 0xc0a1, 0x71); in rt1308_io_init()
274 regmap_write(rt1308->regmap, 0xc210, 0x00); in rt1308_io_init()
275 regmap_write(rt1308->regmap, 0xc070, 0x00); in rt1308_io_init()
276 regmap_write(rt1308->regmap, 0xc100, 0xd7); in rt1308_io_init()
277 regmap_write(rt1308->regmap, 0xc101, 0xd7); in rt1308_io_init()
282 regmap_write(rt1308->regmap, 0xcf01, 0x01); in rt1308_io_init()
285 if (rt1308->first_hw_init) { in rt1308_io_init()
286 regcache_cache_bypass(rt1308->regmap, false); in rt1308_io_init()
287 regcache_mark_dirty(rt1308->regmap); in rt1308_io_init()
289 rt1308->first_hw_init = true; in rt1308_io_init()
292 rt1308->hw_init = true; in rt1308_io_init()
294 pm_runtime_put_autosuspend(&slave->dev); in rt1308_io_init()
296 dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); in rt1308_io_init()
304 struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(&slave->dev); in rt1308_update_status()
307 rt1308->hw_init = false; in rt1308_update_status()
313 if (rt1308->hw_init || status != SDW_SLAVE_ATTACHED) in rt1308_update_status()
317 return rt1308_io_init(&slave->dev, slave); in rt1308_update_status()
323 struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(&slave->dev); in rt1308_bus_config()
326 memcpy(&rt1308->params, params, sizeof(*params)); in rt1308_bus_config()
328 ret = rt1308_clock_config(&slave->dev); in rt1308_bus_config()
330 dev_err(&slave->dev, "Invalid clk config"); in rt1308_bus_config()
338 dev_dbg(&slave->dev, in rt1308_interrupt_callback()
339 "%s control_port_stat=%x", __func__, status->control_port); in rt1308_interrupt_callback()
348 snd_soc_dapm_to_component(w->dapm); in rt1308_classd_event()
511 struct snd_soc_component *component = dai->component; in rt1308_sdw_set_tdm_slot()
516 return -EINVAL; in rt1308_sdw_set_tdm_slot()
519 return -EINVAL; in rt1308_sdw_set_tdm_slot()
521 rt1308->rx_mask = rx_mask; in rt1308_sdw_set_tdm_slot()
522 rt1308->slots = slots; in rt1308_sdw_set_tdm_slot()
531 struct snd_soc_component *component = dai->component; in rt1308_sdw_hw_params()
539 dev_dbg(dai->dev, "%s %s", __func__, dai->name); in rt1308_sdw_hw_params()
543 return -EINVAL; in rt1308_sdw_hw_params()
545 if (!rt1308->sdw_slave) in rt1308_sdw_hw_params()
546 return -EINVAL; in rt1308_sdw_hw_params()
552 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in rt1308_sdw_hw_params()
555 return -EINVAL; in rt1308_sdw_hw_params()
557 if (rt1308->slots) { in rt1308_sdw_hw_params()
558 stream_config.ch_count = rt1308->slots; in rt1308_sdw_hw_params()
559 port_config.ch_mask = rt1308->rx_mask; in rt1308_sdw_hw_params()
562 retval = sdw_stream_add_slave(rt1308->sdw_slave, &stream_config, in rt1308_sdw_hw_params()
565 dev_err(dai->dev, "Unable to configure port\n"); in rt1308_sdw_hw_params()
575 struct snd_soc_component *component = dai->component; in rt1308_sdw_pcm_hw_free()
581 if (!rt1308->sdw_slave) in rt1308_sdw_pcm_hw_free()
582 return -EINVAL; in rt1308_sdw_pcm_hw_free()
584 sdw_stream_remove_slave(rt1308->sdw_slave, sdw_stream); in rt1308_sdw_pcm_hw_free()
603 device_property_read_u32(dev, "realtek,bq-params-cnt", &rt1308->bq_params_cnt); in rt1308_sdw_parse_dt()
604 if (rt1308->bq_params_cnt) { in rt1308_sdw_parse_dt()
605 rt1308->bq_params = devm_kzalloc(dev, rt1308->bq_params_cnt, GFP_KERNEL); in rt1308_sdw_parse_dt()
606 if (!rt1308->bq_params) { in rt1308_sdw_parse_dt()
608 ret = -ENOMEM; in rt1308_sdw_parse_dt()
610 …ret = device_property_read_u8_array(dev, "realtek,bq-params", rt1308->bq_params, rt1308->bq_params… in rt1308_sdw_parse_dt()
612 dev_err(dev, "Could not read list of realtek,bq-params\n"); in rt1308_sdw_parse_dt()
616 dev_dbg(dev, "bq_params_cnt=%d\n", rt1308->bq_params_cnt); in rt1308_sdw_parse_dt()
625 rt1308->component = component; in rt1308_sdw_component_probe()
626 rt1308_sdw_parse_dt(rt1308, &rt1308->sdw_slave->dev); in rt1308_sdw_component_probe()
628 if (!rt1308->first_hw_init) in rt1308_sdw_component_probe()
631 ret = pm_runtime_resume(component->dev); in rt1308_sdw_component_probe()
632 if (ret < 0 && ret != -EACCES) in rt1308_sdw_component_probe()
667 .name = "rt1308-aif",
687 return -ENOMEM; in rt1308_sdw_init()
690 rt1308->sdw_slave = slave; in rt1308_sdw_init()
691 rt1308->regmap = regmap; in rt1308_sdw_init()
693 regcache_cache_only(rt1308->regmap, true); in rt1308_sdw_init()
699 rt1308->hw_init = false; in rt1308_sdw_init()
700 rt1308->first_hw_init = false; in rt1308_sdw_init()
709 /* set autosuspend parameters */ in rt1308_sdw_init()
721 * fail with -EACCESS because of race conditions between card creation and enumeration in rt1308_sdw_init()
739 return rt1308_sdw_init(&slave->dev, regmap, slave); in rt1308_sdw_probe()
744 pm_runtime_disable(&slave->dev); in rt1308_sdw_remove()
759 if (!rt1308->hw_init) in rt1308_dev_suspend()
762 regcache_cache_only(rt1308->regmap, true); in rt1308_dev_suspend()
775 if (!rt1308->first_hw_init) in rt1308_dev_resume()
778 if (!slave->unattach_request) in rt1308_dev_resume()
781 time = wait_for_completion_timeout(&slave->initialization_complete, in rt1308_dev_resume()
784 dev_err(&slave->dev, "Initialization not complete, timed out\n"); in rt1308_dev_resume()
785 sdw_show_ping_status(slave->bus, true); in rt1308_dev_resume()
787 return -ETIMEDOUT; in rt1308_dev_resume()
791 slave->unattach_request = 0; in rt1308_dev_resume()
792 regcache_cache_only(rt1308->regmap, false); in rt1308_dev_resume()
793 regcache_sync_region(rt1308->regmap, 0xc000, 0xcfff); in rt1308_dev_resume()