soc-component.c 33.0 KB
Newer Older
K
Kuninori Morimoto 已提交
1 2 3 4
// SPDX-License-Identifier: GPL-2.0
//
// soc-component.c
//
5
// Copyright 2009-2011 Wolfson Microelectronics PLC.
K
Kuninori Morimoto 已提交
6
// Copyright (C) 2019 Renesas Electronics Corp.
7 8
//
// Mark Brown <broonie@opensource.wolfsonmicro.com>
K
Kuninori Morimoto 已提交
9 10
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
//
11
#include <linux/module.h>
12
#include <linux/pm_runtime.h>
K
Kuninori Morimoto 已提交
13
#include <sound/soc.h>
14
#include <linux/bitops.h>
K
Kuninori Morimoto 已提交
15

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
#define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret)
static inline int _soc_component_ret(struct snd_soc_component *component,
				     const char *func, int ret)
{
	/* Positive/Zero values are not errors */
	if (ret >= 0)
		return ret;

	/* Negative values might be errors */
	switch (ret) {
	case -EPROBE_DEFER:
	case -ENOTSUPP:
		break;
	default:
		dev_err(component->dev,
			"ASoC: error at %s on %s: %d\n",
			func, component->name, ret);
	}

	return ret;
}

38 39 40 41 42 43 44 45 46
static inline int soc_component_field_shift(struct snd_soc_component *component,
					    unsigned int mask)
{
	if (!mask) {
		dev_err(component->dev,	"ASoC: error field mask is zero for %s\n",
			component->name);
		return 0;
	}

47
	return (ffs(mask) - 1);
48 49
}

50 51 52 53 54 55 56 57
/*
 * We might want to check substream by using list.
 * In such case, we can update these macros.
 */
#define soc_component_mark_push(component, substream, tgt)	((component)->mark_##tgt = substream)
#define soc_component_mark_pop(component, substream, tgt)	((component)->mark_##tgt = NULL)
#define soc_component_mark_match(component, substream, tgt)	((component)->mark_##tgt == substream)

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
void snd_soc_component_set_aux(struct snd_soc_component *component,
			       struct snd_soc_aux_dev *aux)
{
	component->init = (aux) ? aux->init : NULL;
}

int snd_soc_component_init(struct snd_soc_component *component)
{
	int ret = 0;

	if (component->init)
		ret = component->init(component);

	return soc_component_ret(component, ret);
}

K
Kuninori Morimoto 已提交
74 75 76 77 78 79 80 81 82 83 84 85 86 87
/**
 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
 * @component: COMPONENT
 * @clk_id: DAI specific clock ID
 * @source: Source for the clock
 * @freq: new clock frequency in Hz
 * @dir: new clock direction - input/output.
 *
 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
 */
int snd_soc_component_set_sysclk(struct snd_soc_component *component,
				 int clk_id, int source, unsigned int freq,
				 int dir)
{
88 89
	int ret = -ENOTSUPP;

K
Kuninori Morimoto 已提交
90
	if (component->driver->set_sysclk)
91
		ret = component->driver->set_sysclk(component, clk_id, source,
K
Kuninori Morimoto 已提交
92 93
						     freq, dir);

94
	return soc_component_ret(component, ret);
K
Kuninori Morimoto 已提交
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
}
EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);

/*
 * snd_soc_component_set_pll - configure component PLL.
 * @component: COMPONENT
 * @pll_id: DAI specific PLL ID
 * @source: DAI specific source for the PLL
 * @freq_in: PLL input clock frequency in Hz
 * @freq_out: requested PLL output clock frequency in Hz
 *
 * Configures and enables PLL to generate output clock based on input clock.
 */
int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
			      int source, unsigned int freq_in,
			      unsigned int freq_out)
{
112 113
	int ret = -EINVAL;

K
Kuninori Morimoto 已提交
114
	if (component->driver->set_pll)
115
		ret = component->driver->set_pll(component, pll_id, source,
K
Kuninori Morimoto 已提交
116 117
						  freq_in, freq_out);

118
	return soc_component_ret(component, ret);
K
Kuninori Morimoto 已提交
119 120 121
}
EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);

122 123 124 125 126 127 128
void snd_soc_component_seq_notifier(struct snd_soc_component *component,
				    enum snd_soc_dapm_type type, int subseq)
{
	if (component->driver->seq_notifier)
		component->driver->seq_notifier(component, type, subseq);
}

129 130 131
int snd_soc_component_stream_event(struct snd_soc_component *component,
				   int event)
{
132 133
	int ret = 0;

134
	if (component->driver->stream_event)
135
		ret = component->driver->stream_event(component, event);
136

137
	return soc_component_ret(component, ret);
138 139
}

140 141 142
int snd_soc_component_set_bias_level(struct snd_soc_component *component,
				     enum snd_soc_bias_level level)
{
143 144
	int ret = 0;

145
	if (component->driver->set_bias_level)
146
		ret = component->driver->set_bias_level(component, level);
147

148
	return soc_component_ret(component, ret);
149 150
}

151 152 153
int snd_soc_component_enable_pin(struct snd_soc_component *component,
				 const char *pin)
{
154 155 156
	struct snd_soc_dapm_context *dapm =
		snd_soc_component_get_dapm(component);
	return snd_soc_dapm_enable_pin(dapm, pin);
157
}
K
Kuninori Morimoto 已提交
158 159 160 161 162
EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);

int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
					  const char *pin)
{
163 164 165
	struct snd_soc_dapm_context *dapm =
		snd_soc_component_get_dapm(component);
	return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
K
Kuninori Morimoto 已提交
166 167 168 169 170 171
}
EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);

int snd_soc_component_disable_pin(struct snd_soc_component *component,
				  const char *pin)
{
172 173 174
	struct snd_soc_dapm_context *dapm =
		snd_soc_component_get_dapm(component);
	return snd_soc_dapm_disable_pin(dapm, pin);
K
Kuninori Morimoto 已提交
175 176 177 178 179 180
}
EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);

int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
					   const char *pin)
{
181 182 183
	struct snd_soc_dapm_context *dapm = 
		snd_soc_component_get_dapm(component);
	return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
K
Kuninori Morimoto 已提交
184 185 186 187 188 189
}
EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);

int snd_soc_component_nc_pin(struct snd_soc_component *component,
			     const char *pin)
{
190 191 192
	struct snd_soc_dapm_context *dapm =
		snd_soc_component_get_dapm(component);
	return snd_soc_dapm_nc_pin(dapm, pin);
K
Kuninori Morimoto 已提交
193 194 195 196 197 198
}
EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);

int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
				      const char *pin)
{
199 200 201
	struct snd_soc_dapm_context *dapm =
		snd_soc_component_get_dapm(component);
	return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
K
Kuninori Morimoto 已提交
202 203 204 205 206 207
}
EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);

int snd_soc_component_get_pin_status(struct snd_soc_component *component,
				     const char *pin)
{
208 209 210
	struct snd_soc_dapm_context *dapm =
		snd_soc_component_get_dapm(component);
	return snd_soc_dapm_get_pin_status(dapm, pin);
K
Kuninori Morimoto 已提交
211 212 213 214 215 216
}
EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);

int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
				       const char *pin)
{
217 218 219
	struct snd_soc_dapm_context *dapm =
		snd_soc_component_get_dapm(component);
	return snd_soc_dapm_force_enable_pin(dapm, pin);
K
Kuninori Morimoto 已提交
220 221 222 223 224 225 226
}
EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);

int snd_soc_component_force_enable_pin_unlocked(
	struct snd_soc_component *component,
	const char *pin)
{
227 228 229
	struct snd_soc_dapm_context *dapm =
		snd_soc_component_get_dapm(component);
	return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
K
Kuninori Morimoto 已提交
230 231 232 233 234 235 236 237 238 239 240 241 242 243
}
EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);

/**
 * snd_soc_component_set_jack - configure component jack.
 * @component: COMPONENTs
 * @jack: structure to use for the jack
 * @data: can be used if codec driver need extra data for configuring jack
 *
 * Configures and enables jack detection function.
 */
int snd_soc_component_set_jack(struct snd_soc_component *component,
			       struct snd_soc_jack *jack, void *data)
{
244 245
	int ret = -ENOTSUPP;

K
Kuninori Morimoto 已提交
246
	if (component->driver->set_jack)
247
		ret = component->driver->set_jack(component, jack, data);
K
Kuninori Morimoto 已提交
248

249
	return soc_component_ret(component, ret);
K
Kuninori Morimoto 已提交
250 251
}
EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
252 253

int snd_soc_component_module_get(struct snd_soc_component *component,
254
				 struct snd_pcm_substream *substream,
255 256
				 int upon_open)
{
257 258
	int ret = 0;

259 260
	if (component->driver->module_get_upon_open == !!upon_open &&
	    !try_module_get(component->dev->driver->owner))
261
		ret = -ENODEV;
262

263 264 265 266
	/* mark substream if succeeded */
	if (ret == 0)
		soc_component_mark_push(component, substream, module);

267
	return soc_component_ret(component, ret);
268 269 270
}

void snd_soc_component_module_put(struct snd_soc_component *component,
271 272
				  struct snd_pcm_substream *substream,
				  int upon_open, int rollback)
273
{
274 275 276
	if (rollback && !soc_component_mark_match(component, substream, module))
		return;

277 278
	if (component->driver->module_get_upon_open == !!upon_open)
		module_put(component->dev->driver->owner);
279 280 281

	/* remove marked substream */
	soc_component_mark_pop(component, substream, module);
282
}
283 284 285 286

int snd_soc_component_open(struct snd_soc_component *component,
			   struct snd_pcm_substream *substream)
{
287 288
	int ret = 0;

289
	if (component->driver->open)
290 291
		ret = component->driver->open(component, substream);

292 293 294 295
	/* mark substream if succeeded */
	if (ret == 0)
		soc_component_mark_push(component, substream, open);

296
	return soc_component_ret(component, ret);
297
}
298 299

int snd_soc_component_close(struct snd_soc_component *component,
300 301
			    struct snd_pcm_substream *substream,
			    int rollback)
302
{
303 304
	int ret = 0;

305 306 307
	if (rollback && !soc_component_mark_match(component, substream, open))
		return 0;

308
	if (component->driver->close)
309 310
		ret = component->driver->close(component, substream);

311 312 313
	/* remove marked substream */
	soc_component_mark_pop(component, substream, open);

314
	return soc_component_ret(component, ret);
315
}
316

317 318 319 320 321 322
void snd_soc_component_suspend(struct snd_soc_component *component)
{
	if (component->driver->suspend)
		component->driver->suspend(component);
	component->suspended = 1;
}
323 324 325 326 327 328 329

void snd_soc_component_resume(struct snd_soc_component *component)
{
	if (component->driver->resume)
		component->driver->resume(component);
	component->suspended = 0;
}
330 331 332 333 334

int snd_soc_component_is_suspended(struct snd_soc_component *component)
{
	return component->suspended;
}
335 336 337

int snd_soc_component_probe(struct snd_soc_component *component)
{
338 339
	int ret = 0;

340
	if (component->driver->probe)
341
		ret = component->driver->probe(component);
342

343
	return soc_component_ret(component, ret);
344
}
345 346 347 348 349 350

void snd_soc_component_remove(struct snd_soc_component *component)
{
	if (component->driver->remove)
		component->driver->remove(component);
}
351 352 353 354

int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
				      struct device_node *ep)
{
355 356
	int ret = -ENOTSUPP;

357
	if (component->driver->of_xlate_dai_id)
358
		ret = component->driver->of_xlate_dai_id(component, ep);
359

360
	return soc_component_ret(component, ret);
361
}
362 363

int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
364
					const struct of_phandle_args *args,
365 366 367
					const char **dai_name)
{
	if (component->driver->of_xlate_dai_name)
368 369 370 371 372 373 374 375
		return component->driver->of_xlate_dai_name(component,
							    args, dai_name);
	/*
	 * Don't use soc_component_ret here because we may not want to report
	 * the error just yet. If a device has more than one component, the
	 * first may not match and we don't want spam the log with this.
	 */
	return -ENOTSUPP;
376
}
377

378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
void snd_soc_component_setup_regmap(struct snd_soc_component *component)
{
	int val_bytes = regmap_get_val_bytes(component->regmap);

	/* Errors are legitimate for non-integer byte multiples */
	if (val_bytes > 0)
		component->val_bytes = val_bytes;
}

#ifdef CONFIG_REGMAP

/**
 * snd_soc_component_init_regmap() - Initialize regmap instance for the
 *                                   component
 * @component: The component for which to initialize the regmap instance
 * @regmap: The regmap instance that should be used by the component
 *
 * This function allows deferred assignment of the regmap instance that is
 * associated with the component. Only use this if the regmap instance is not
 * yet ready when the component is registered. The function must also be called
 * before the first IO attempt of the component.
 */
void snd_soc_component_init_regmap(struct snd_soc_component *component,
				   struct regmap *regmap)
{
	component->regmap = regmap;
	snd_soc_component_setup_regmap(component);
}
EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);

/**
 * snd_soc_component_exit_regmap() - De-initialize regmap instance for the
 *                                   component
 * @component: The component for which to de-initialize the regmap instance
 *
 * Calls regmap_exit() on the regmap instance associated to the component and
 * removes the regmap instance from the component.
 *
 * This function should only be used if snd_soc_component_init_regmap() was used
 * to initialize the regmap instance.
 */
void snd_soc_component_exit_regmap(struct snd_soc_component *component)
{
	regmap_exit(component->regmap);
	component->regmap = NULL;
}
EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);

#endif

428
int snd_soc_component_compr_open(struct snd_compr_stream *cstream)
429 430 431 432 433 434 435 436 437
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->open) {
			ret = component->driver->compress_ops->open(component, cstream);
438
			if (ret < 0)
439 440
				return soc_component_ret(component, ret);
		}
441
		soc_component_mark_push(component, cstream, compr_open);
442 443 444 445 446 447
	}

	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_open);

448
void snd_soc_component_compr_free(struct snd_compr_stream *cstream,
449
				  int rollback)
450 451 452 453 454 455
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i;

	for_each_rtd_components(rtd, i, component) {
456 457
		if (rollback && !soc_component_mark_match(component, cstream, compr_open))
			continue;
458 459 460 461

		if (component->driver->compress_ops &&
		    component->driver->compress_ops->free)
			component->driver->compress_ops->free(component, cstream);
462 463

		soc_component_mark_pop(component, cstream, compr_open);
464 465 466 467
	}
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_free);

468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
int snd_soc_component_compr_trigger(struct snd_compr_stream *cstream, int cmd)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->trigger) {
			ret = component->driver->compress_ops->trigger(
				component, cstream, cmd);
			if (ret < 0)
				return soc_component_ret(component, ret);
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_trigger);

488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
int snd_soc_component_compr_set_params(struct snd_compr_stream *cstream,
				       struct snd_compr_params *params)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->set_params) {
			ret = component->driver->compress_ops->set_params(
				component, cstream, params);
			if (ret < 0)
				return soc_component_ret(component, ret);
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_set_params);

509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
int snd_soc_component_compr_get_params(struct snd_compr_stream *cstream,
				       struct snd_codec *params)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->get_params) {
			ret = component->driver->compress_ops->get_params(
				component, cstream, params);
			return soc_component_ret(component, ret);
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_get_params);

529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
int snd_soc_component_compr_get_caps(struct snd_compr_stream *cstream,
				     struct snd_compr_caps *caps)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret = 0;

	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->get_caps) {
			ret = component->driver->compress_ops->get_caps(
				component, cstream, caps);
			break;
		}
	}

	mutex_unlock(&rtd->card->pcm_mutex);

	return soc_component_ret(component, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_get_caps);

553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
int snd_soc_component_compr_get_codec_caps(struct snd_compr_stream *cstream,
					   struct snd_compr_codec_caps *codec)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret = 0;

	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->get_codec_caps) {
			ret = component->driver->compress_ops->get_codec_caps(
				component, cstream, codec);
			break;
		}
	}

	mutex_unlock(&rtd->card->pcm_mutex);

	return soc_component_ret(component, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_get_codec_caps);

577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->ack) {
			ret = component->driver->compress_ops->ack(
				component, cstream, bytes);
			if (ret < 0)
				return soc_component_ret(component, ret);
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_ack);

597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,
				    struct snd_compr_tstamp *tstamp)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->pointer) {
			ret = component->driver->compress_ops->pointer(
				component, cstream, tstamp);
			return soc_component_ret(component, ret);
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_pointer);

617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
int snd_soc_component_compr_copy(struct snd_compr_stream *cstream,
				 char __user *buf, size_t count)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret = 0;

	mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->copy) {
			ret = component->driver->compress_ops->copy(
				component, cstream, buf, count);
			break;
		}
	}

	mutex_unlock(&rtd->card->pcm_mutex);

	return soc_component_ret(component, ret);
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_copy);

641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
int snd_soc_component_compr_set_metadata(struct snd_compr_stream *cstream,
					 struct snd_compr_metadata *metadata)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->set_metadata) {
			ret = component->driver->compress_ops->set_metadata(
				component, cstream, metadata);
			if (ret < 0)
				return soc_component_ret(component, ret);
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_set_metadata);

662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
int snd_soc_component_compr_get_metadata(struct snd_compr_stream *cstream,
					 struct snd_compr_metadata *metadata)
{
	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->compress_ops &&
		    component->driver->compress_ops->get_metadata) {
			ret = component->driver->compress_ops->get_metadata(
				component, cstream, metadata);
			return soc_component_ret(component, ret);
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_component_compr_get_metadata);

682 683 684
static unsigned int soc_component_read_no_lock(
	struct snd_soc_component *component,
	unsigned int reg)
685 686
{
	int ret;
687
	unsigned int val = 0;
688 689

	if (component->regmap)
690
		ret = regmap_read(component->regmap, reg, &val);
691 692
	else if (component->driver->read) {
		ret = 0;
693
		val = component->driver->read(component, reg);
694 695 696 697 698
	}
	else
		ret = -EIO;

	if (ret < 0)
699
		return soc_component_ret(component, ret);
700 701 702

	return val;
}
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721

/**
 * snd_soc_component_read() - Read register value
 * @component: Component to read from
 * @reg: Register to read
 *
 * Return: read value
 */
unsigned int snd_soc_component_read(struct snd_soc_component *component,
				    unsigned int reg)
{
	unsigned int val;

	mutex_lock(&component->io_mutex);
	val = soc_component_read_no_lock(component, reg);
	mutex_unlock(&component->io_mutex);

	return val;
}
722
EXPORT_SYMBOL_GPL(snd_soc_component_read);
723

724 725 726 727 728 729 730 731 732 733 734 735 736 737
static int soc_component_write_no_lock(
	struct snd_soc_component *component,
	unsigned int reg, unsigned int val)
{
	int ret = -EIO;

	if (component->regmap)
		ret = regmap_write(component->regmap, reg, val);
	else if (component->driver->write)
		ret = component->driver->write(component, reg, val);

	return soc_component_ret(component, ret);
}

738 739 740 741 742 743 744 745 746 747 748
/**
 * snd_soc_component_write() - Write register value
 * @component: Component to write to
 * @reg: Register to write
 * @val: Value to write to the register
 *
 * Return: 0 on success, a negative error code otherwise.
 */
int snd_soc_component_write(struct snd_soc_component *component,
			    unsigned int reg, unsigned int val)
{
749
	int ret;
750

751 752 753
	mutex_lock(&component->io_mutex);
	ret = soc_component_write_no_lock(component, reg, val);
	mutex_unlock(&component->io_mutex);
754

755
	return ret;
756 757 758 759 760 761 762 763
}
EXPORT_SYMBOL_GPL(snd_soc_component_write);

static int snd_soc_component_update_bits_legacy(
	struct snd_soc_component *component, unsigned int reg,
	unsigned int mask, unsigned int val, bool *change)
{
	unsigned int old, new;
764
	int ret = 0;
765 766 767

	mutex_lock(&component->io_mutex);

768
	old = soc_component_read_no_lock(component, reg);
769 770 771 772

	new = (old & ~mask) | (val & mask);
	*change = old != new;
	if (*change)
773
		ret = soc_component_write_no_lock(component, reg, new);
774

775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845
	mutex_unlock(&component->io_mutex);

	return soc_component_ret(component, ret);
}

/**
 * snd_soc_component_update_bits() - Perform read/modify/write cycle
 * @component: Component to update
 * @reg: Register to update
 * @mask: Mask that specifies which bits to update
 * @val: New value for the bits specified by mask
 *
 * Return: 1 if the operation was successful and the value of the register
 * changed, 0 if the operation was successful, but the value did not change.
 * Returns a negative error code otherwise.
 */
int snd_soc_component_update_bits(struct snd_soc_component *component,
				  unsigned int reg, unsigned int mask, unsigned int val)
{
	bool change;
	int ret;

	if (component->regmap)
		ret = regmap_update_bits_check(component->regmap, reg, mask,
					       val, &change);
	else
		ret = snd_soc_component_update_bits_legacy(component, reg,
							   mask, val, &change);

	if (ret < 0)
		return soc_component_ret(component, ret);
	return change;
}
EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);

/**
 * snd_soc_component_update_bits_async() - Perform asynchronous
 *  read/modify/write cycle
 * @component: Component to update
 * @reg: Register to update
 * @mask: Mask that specifies which bits to update
 * @val: New value for the bits specified by mask
 *
 * This function is similar to snd_soc_component_update_bits(), but the update
 * operation is scheduled asynchronously. This means it may not be completed
 * when the function returns. To make sure that all scheduled updates have been
 * completed snd_soc_component_async_complete() must be called.
 *
 * Return: 1 if the operation was successful and the value of the register
 * changed, 0 if the operation was successful, but the value did not change.
 * Returns a negative error code otherwise.
 */
int snd_soc_component_update_bits_async(struct snd_soc_component *component,
					unsigned int reg, unsigned int mask, unsigned int val)
{
	bool change;
	int ret;

	if (component->regmap)
		ret = regmap_update_bits_check_async(component->regmap, reg,
						     mask, val, &change);
	else
		ret = snd_soc_component_update_bits_legacy(component, reg,
							   mask, val, &change);

	if (ret < 0)
		return soc_component_ret(component, ret);
	return change;
}
EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);

846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886
/**
 * snd_soc_component_read_field() - Read register field value
 * @component: Component to read from
 * @reg: Register to read
 * @mask: mask of the register field
 *
 * Return: read value of register field.
 */
unsigned int snd_soc_component_read_field(struct snd_soc_component *component,
					  unsigned int reg, unsigned int mask)
{
	unsigned int val;

	val = snd_soc_component_read(component, reg);

	val = (val & mask) >> soc_component_field_shift(component, mask);

	return val;
}
EXPORT_SYMBOL_GPL(snd_soc_component_read_field);

/**
 * snd_soc_component_write_field() - write to register field
 * @component: Component to write to
 * @reg: Register to write
 * @mask: mask of the register field to update
 * @val: value of the field to write
 *
 * Return: 1 for change, otherwise 0.
 */
int snd_soc_component_write_field(struct snd_soc_component *component,
				  unsigned int reg, unsigned int mask,
				  unsigned int val)
{

	val = (val << soc_component_field_shift(component, mask)) & mask;

	return snd_soc_component_update_bits(component, reg, mask, val);
}
EXPORT_SYMBOL_GPL(snd_soc_component_write_field);

887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
/**
 * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
 * @component: Component for which to wait
 *
 * This function blocks until all asynchronous I/O which has previously been
 * scheduled using snd_soc_component_update_bits_async() has completed.
 */
void snd_soc_component_async_complete(struct snd_soc_component *component)
{
	if (component->regmap)
		regmap_async_complete(component->regmap);
}
EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);

/**
 * snd_soc_component_test_bits - Test register for change
 * @component: component
 * @reg: Register to test
 * @mask: Mask that specifies which bits to test
 * @value: Value to test against
 *
 * Tests a register with a new value and checks if the new value is
 * different from the old value.
 *
 * Return: 1 for change, otherwise 0.
 */
int snd_soc_component_test_bits(struct snd_soc_component *component,
				unsigned int reg, unsigned int mask, unsigned int value)
{
	unsigned int old, new;

918
	old = snd_soc_component_read(component, reg);
919 920 921 922 923
	new = (old & ~mask) | value;
	return old != new;
}
EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);

924 925
int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
{
926
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
927
	struct snd_soc_component *component;
928
	int i;
929

930
	/* FIXME: use 1st pointer */
931
	for_each_rtd_components(rtd, i, component)
932 933
		if (component->driver->pointer)
			return component->driver->pointer(component, substream);
934 935 936

	return 0;
}
937 938 939 940

int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
				unsigned int cmd, void *arg)
{
941
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
942
	struct snd_soc_component *component;
943
	int i;
944

945
	/* FIXME: use 1st ioctl */
946
	for_each_rtd_components(rtd, i, component)
947
		if (component->driver->ioctl)
948 949 950 951
			return soc_component_ret(
				component,
				component->driver->ioctl(component,
							 substream, cmd, arg));
952 953 954

	return snd_pcm_lib_ioctl(substream, cmd, arg);
}
955

956 957
int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
{
958
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
959
	struct snd_soc_component *component;
960
	int i, ret;
961

962
	for_each_rtd_components(rtd, i, component) {
963
		if (component->driver->sync_stop) {
964 965 966
			ret = component->driver->sync_stop(component,
							   substream);
			if (ret < 0)
967
				return soc_component_ret(component, ret);
968 969 970 971 972 973
		}
	}

	return 0;
}

974 975 976 977
int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
				    int channel, unsigned long pos,
				    void __user *buf, unsigned long bytes)
{
978
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
979
	struct snd_soc_component *component;
980
	int i;
981

982
	/* FIXME. it returns 1st copy now */
983
	for_each_rtd_components(rtd, i, component)
984
		if (component->driver->copy_user)
985 986 987 988 989
			return soc_component_ret(
				component,
				component->driver->copy_user(
					component, substream, channel,
					pos, buf, bytes));
990 991 992

	return -EINVAL;
}
993 994 995 996

struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
					unsigned long offset)
{
997
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
998 999
	struct snd_soc_component *component;
	struct page *page;
1000
	int i;
1001

1002
	/* FIXME. it returns 1st page now */
1003
	for_each_rtd_components(rtd, i, component) {
1004 1005 1006 1007 1008 1009
		if (component->driver->page) {
			page = component->driver->page(component,
						       substream, offset);
			if (page)
				return page;
		}
1010 1011 1012 1013
	}

	return NULL;
}
1014 1015 1016 1017

int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
			       struct vm_area_struct *vma)
{
1018
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1019
	struct snd_soc_component *component;
1020
	int i;
1021

1022
	/* FIXME. it returns 1st mmap now */
1023
	for_each_rtd_components(rtd, i, component)
1024
		if (component->driver->mmap)
1025
			return soc_component_ret(
1026 1027 1028
				component,
				component->driver->mmap(component,
							substream, vma));
1029 1030 1031

	return -EINVAL;
}
1032

1033
int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
1034 1035 1036
{
	struct snd_soc_component *component;
	int ret;
1037
	int i;
1038

1039
	for_each_rtd_components(rtd, i, component) {
1040 1041 1042
		if (component->driver->pcm_construct) {
			ret = component->driver->pcm_construct(component, rtd);
			if (ret < 0)
1043
				return soc_component_ret(component, ret);
1044
		}
1045 1046 1047 1048
	}

	return 0;
}
1049

1050
void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
1051 1052
{
	struct snd_soc_component *component;
1053
	int i;
1054

1055 1056 1057
	if (!rtd->pcm)
		return;

1058
	for_each_rtd_components(rtd, i, component)
1059
		if (component->driver->pcm_destruct)
1060
			component->driver->pcm_destruct(component, rtd->pcm);
1061
}
1062 1063 1064

int snd_soc_pcm_component_prepare(struct snd_pcm_substream *substream)
{
1065
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->prepare) {
			ret = component->driver->prepare(component, substream);
			if (ret < 0)
				return soc_component_ret(component, ret);
		}
	}

	return 0;
}
1079 1080

int snd_soc_pcm_component_hw_params(struct snd_pcm_substream *substream,
1081
				    struct snd_pcm_hw_params *params)
1082
{
1083
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1084 1085 1086 1087 1088 1089 1090
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		if (component->driver->hw_params) {
			ret = component->driver->hw_params(component,
							   substream, params);
1091
			if (ret < 0)
1092 1093
				return soc_component_ret(component, ret);
		}
1094 1095
		/* mark substream if succeeded */
		soc_component_mark_push(component, substream, hw_params);
1096 1097 1098 1099
	}

	return 0;
}
1100 1101

void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
1102
				   int rollback)
1103
{
1104
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1105 1106 1107 1108
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
1109 1110
		if (rollback && !soc_component_mark_match(component, substream, hw_params))
			continue;
1111 1112 1113 1114 1115 1116

		if (component->driver->hw_free) {
			ret = component->driver->hw_free(component, substream);
			if (ret < 0)
				soc_component_ret(component, ret);
		}
1117 1118 1119

		/* remove marked substream */
		soc_component_mark_pop(component, substream, hw_params);
1120 1121
	}
}
1122

1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
static int soc_component_trigger(struct snd_soc_component *component,
				 struct snd_pcm_substream *substream,
				 int cmd)
{
	int ret = 0;

	if (component->driver->trigger)
		ret = component->driver->trigger(component, substream, cmd);

	return soc_component_ret(component, ret);
}

1135
int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
1136
				  int cmd, int rollback)
1137
{
1138
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1139
	struct snd_soc_component *component;
1140 1141 1142 1143 1144 1145 1146 1147
	int i, r, ret = 0;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		for_each_rtd_components(rtd, i, component) {
			ret = soc_component_trigger(component, substream, cmd);
1148
			if (ret < 0)
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
				break;
			soc_component_mark_push(component, substream, trigger);
		}
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		for_each_rtd_components(rtd, i, component) {
			if (rollback && !soc_component_mark_match(component, substream, trigger))
				continue;

			r = soc_component_trigger(component, substream, cmd);
			if (r < 0)
				ret = r; /* use last ret */
			soc_component_mark_pop(component, substream, trigger);
1164 1165 1166
		}
	}

1167
	return ret;
1168
}
1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205

int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd,
					 void *stream)
{
	struct snd_soc_component *component;
	int i, ret;

	for_each_rtd_components(rtd, i, component) {
		ret = pm_runtime_get_sync(component->dev);
		if (ret < 0 && ret != -EACCES) {
			pm_runtime_put_noidle(component->dev);
			return soc_component_ret(component, ret);
		}
		/* mark stream if succeeded */
		soc_component_mark_push(component, stream, pm);
	}

	return 0;
}

void snd_soc_pcm_component_pm_runtime_put(struct snd_soc_pcm_runtime *rtd,
					  void *stream, int rollback)
{
	struct snd_soc_component *component;
	int i;

	for_each_rtd_components(rtd, i, component) {
		if (rollback && !soc_component_mark_match(component, stream, pm))
			continue;

		pm_runtime_mark_last_busy(component->dev);
		pm_runtime_put_autosuspend(component->dev);

		/* remove marked stream */
		soc_component_mark_pop(component, stream, pm);
	}
}
1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219

int snd_soc_pcm_component_ack(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct snd_soc_component *component;
	int i;

	/* FIXME: use 1st pointer */
	for_each_rtd_components(rtd, i, component)
		if (component->driver->ack)
			return component->driver->ack(component, substream);

	return 0;
}