linux/sound/soc/soc-component.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// soc-component.c
   4//
   5// Copyright (C) 2019 Renesas Electronics Corp.
   6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
   7//
   8#include <linux/module.h>
   9#include <sound/soc.h>
  10
  11/**
  12 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
  13 * @component: COMPONENT
  14 * @clk_id: DAI specific clock ID
  15 * @source: Source for the clock
  16 * @freq: new clock frequency in Hz
  17 * @dir: new clock direction - input/output.
  18 *
  19 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
  20 */
  21int snd_soc_component_set_sysclk(struct snd_soc_component *component,
  22                                 int clk_id, int source, unsigned int freq,
  23                                 int dir)
  24{
  25        if (component->driver->set_sysclk)
  26                return component->driver->set_sysclk(component, clk_id, source,
  27                                                     freq, dir);
  28
  29        return -ENOTSUPP;
  30}
  31EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
  32
  33/*
  34 * snd_soc_component_set_pll - configure component PLL.
  35 * @component: COMPONENT
  36 * @pll_id: DAI specific PLL ID
  37 * @source: DAI specific source for the PLL
  38 * @freq_in: PLL input clock frequency in Hz
  39 * @freq_out: requested PLL output clock frequency in Hz
  40 *
  41 * Configures and enables PLL to generate output clock based on input clock.
  42 */
  43int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
  44                              int source, unsigned int freq_in,
  45                              unsigned int freq_out)
  46{
  47        if (component->driver->set_pll)
  48                return component->driver->set_pll(component, pll_id, source,
  49                                                  freq_in, freq_out);
  50
  51        return -EINVAL;
  52}
  53EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
  54
  55void snd_soc_component_seq_notifier(struct snd_soc_component *component,
  56                                    enum snd_soc_dapm_type type, int subseq)
  57{
  58        if (component->driver->seq_notifier)
  59                component->driver->seq_notifier(component, type, subseq);
  60}
  61
  62int snd_soc_component_stream_event(struct snd_soc_component *component,
  63                                   int event)
  64{
  65        if (component->driver->stream_event)
  66                return component->driver->stream_event(component, event);
  67
  68        return 0;
  69}
  70
  71int snd_soc_component_set_bias_level(struct snd_soc_component *component,
  72                                     enum snd_soc_bias_level level)
  73{
  74        if (component->driver->set_bias_level)
  75                return component->driver->set_bias_level(component, level);
  76
  77        return 0;
  78}
  79
  80int snd_soc_component_enable_pin(struct snd_soc_component *component,
  81                                 const char *pin)
  82{
  83        struct snd_soc_dapm_context *dapm =
  84                snd_soc_component_get_dapm(component);
  85        char *full_name;
  86        int ret;
  87
  88        if (!component->name_prefix)
  89                return snd_soc_dapm_enable_pin(dapm, pin);
  90
  91        full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
  92        if (!full_name)
  93                return -ENOMEM;
  94
  95        ret = snd_soc_dapm_enable_pin(dapm, full_name);
  96        kfree(full_name);
  97
  98        return ret;
  99}
 100EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
 101
 102int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
 103                                          const char *pin)
 104{
 105        struct snd_soc_dapm_context *dapm =
 106                snd_soc_component_get_dapm(component);
 107        char *full_name;
 108        int ret;
 109
 110        if (!component->name_prefix)
 111                return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
 112
 113        full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
 114        if (!full_name)
 115                return -ENOMEM;
 116
 117        ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name);
 118        kfree(full_name);
 119
 120        return ret;
 121}
 122EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
 123
 124int snd_soc_component_disable_pin(struct snd_soc_component *component,
 125                                  const char *pin)
 126{
 127        struct snd_soc_dapm_context *dapm =
 128                snd_soc_component_get_dapm(component);
 129        char *full_name;
 130        int ret;
 131
 132        if (!component->name_prefix)
 133                return snd_soc_dapm_disable_pin(dapm, pin);
 134
 135        full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
 136        if (!full_name)
 137                return -ENOMEM;
 138
 139        ret = snd_soc_dapm_disable_pin(dapm, full_name);
 140        kfree(full_name);
 141
 142        return ret;
 143}
 144EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
 145
 146int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
 147                                           const char *pin)
 148{
 149        struct snd_soc_dapm_context *dapm =
 150                snd_soc_component_get_dapm(component);
 151        char *full_name;
 152        int ret;
 153
 154        if (!component->name_prefix)
 155                return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
 156
 157        full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
 158        if (!full_name)
 159                return -ENOMEM;
 160
 161        ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name);
 162        kfree(full_name);
 163
 164        return ret;
 165}
 166EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
 167
 168int snd_soc_component_nc_pin(struct snd_soc_component *component,
 169                             const char *pin)
 170{
 171        struct snd_soc_dapm_context *dapm =
 172                snd_soc_component_get_dapm(component);
 173        char *full_name;
 174        int ret;
 175
 176        if (!component->name_prefix)
 177                return snd_soc_dapm_nc_pin(dapm, pin);
 178
 179        full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
 180        if (!full_name)
 181                return -ENOMEM;
 182
 183        ret = snd_soc_dapm_nc_pin(dapm, full_name);
 184        kfree(full_name);
 185
 186        return ret;
 187}
 188EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
 189
 190int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
 191                                      const char *pin)
 192{
 193        struct snd_soc_dapm_context *dapm =
 194                snd_soc_component_get_dapm(component);
 195        char *full_name;
 196        int ret;
 197
 198        if (!component->name_prefix)
 199                return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
 200
 201        full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
 202        if (!full_name)
 203                return -ENOMEM;
 204
 205        ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name);
 206        kfree(full_name);
 207
 208        return ret;
 209}
 210EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
 211
 212int snd_soc_component_get_pin_status(struct snd_soc_component *component,
 213                                     const char *pin)
 214{
 215        struct snd_soc_dapm_context *dapm =
 216                snd_soc_component_get_dapm(component);
 217        char *full_name;
 218        int ret;
 219
 220        if (!component->name_prefix)
 221                return snd_soc_dapm_get_pin_status(dapm, pin);
 222
 223        full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
 224        if (!full_name)
 225                return -ENOMEM;
 226
 227        ret = snd_soc_dapm_get_pin_status(dapm, full_name);
 228        kfree(full_name);
 229
 230        return ret;
 231}
 232EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
 233
 234int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
 235                                       const char *pin)
 236{
 237        struct snd_soc_dapm_context *dapm =
 238                snd_soc_component_get_dapm(component);
 239        char *full_name;
 240        int ret;
 241
 242        if (!component->name_prefix)
 243                return snd_soc_dapm_force_enable_pin(dapm, pin);
 244
 245        full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
 246        if (!full_name)
 247                return -ENOMEM;
 248
 249        ret = snd_soc_dapm_force_enable_pin(dapm, full_name);
 250        kfree(full_name);
 251
 252        return ret;
 253}
 254EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
 255
 256int snd_soc_component_force_enable_pin_unlocked(
 257        struct snd_soc_component *component,
 258        const char *pin)
 259{
 260        struct snd_soc_dapm_context *dapm =
 261                snd_soc_component_get_dapm(component);
 262        char *full_name;
 263        int ret;
 264
 265        if (!component->name_prefix)
 266                return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
 267
 268        full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
 269        if (!full_name)
 270                return -ENOMEM;
 271
 272        ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name);
 273        kfree(full_name);
 274
 275        return ret;
 276}
 277EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
 278
 279/**
 280 * snd_soc_component_set_jack - configure component jack.
 281 * @component: COMPONENTs
 282 * @jack: structure to use for the jack
 283 * @data: can be used if codec driver need extra data for configuring jack
 284 *
 285 * Configures and enables jack detection function.
 286 */
 287int snd_soc_component_set_jack(struct snd_soc_component *component,
 288                               struct snd_soc_jack *jack, void *data)
 289{
 290        if (component->driver->set_jack)
 291                return component->driver->set_jack(component, jack, data);
 292
 293        return -ENOTSUPP;
 294}
 295EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
 296
 297int snd_soc_component_module_get(struct snd_soc_component *component,
 298                                 int upon_open)
 299{
 300        if (component->driver->module_get_upon_open == !!upon_open &&
 301            !try_module_get(component->dev->driver->owner))
 302                return -ENODEV;
 303
 304        return 0;
 305}
 306
 307void snd_soc_component_module_put(struct snd_soc_component *component,
 308                                  int upon_open)
 309{
 310        if (component->driver->module_get_upon_open == !!upon_open)
 311                module_put(component->dev->driver->owner);
 312}
 313
 314int snd_soc_component_open(struct snd_soc_component *component,
 315                           struct snd_pcm_substream *substream)
 316{
 317        if (component->driver->open)
 318                return component->driver->open(component, substream);
 319        return 0;
 320}
 321
 322int snd_soc_component_close(struct snd_soc_component *component,
 323                            struct snd_pcm_substream *substream)
 324{
 325        if (component->driver->close)
 326                return component->driver->close(component, substream);
 327        return 0;
 328}
 329
 330int snd_soc_component_prepare(struct snd_soc_component *component,
 331                              struct snd_pcm_substream *substream)
 332{
 333        if (component->driver->prepare)
 334                return component->driver->prepare(component, substream);
 335        return 0;
 336}
 337
 338int snd_soc_component_hw_params(struct snd_soc_component *component,
 339                                struct snd_pcm_substream *substream,
 340                                struct snd_pcm_hw_params *params)
 341{
 342        if (component->driver->hw_params)
 343                return component->driver->hw_params(component,
 344                                                    substream, params);
 345        return 0;
 346}
 347
 348int snd_soc_component_hw_free(struct snd_soc_component *component,
 349                               struct snd_pcm_substream *substream)
 350{
 351        if (component->driver->hw_free)
 352                return component->driver->hw_free(component, substream);
 353        return 0;
 354}
 355
 356int snd_soc_component_trigger(struct snd_soc_component *component,
 357                              struct snd_pcm_substream *substream,
 358                              int cmd)
 359{
 360        if (component->driver->trigger)
 361                return component->driver->trigger(component, substream, cmd);
 362        return 0;
 363}
 364
 365void snd_soc_component_suspend(struct snd_soc_component *component)
 366{
 367        if (component->driver->suspend)
 368                component->driver->suspend(component);
 369        component->suspended = 1;
 370}
 371
 372void snd_soc_component_resume(struct snd_soc_component *component)
 373{
 374        if (component->driver->resume)
 375                component->driver->resume(component);
 376        component->suspended = 0;
 377}
 378
 379int snd_soc_component_is_suspended(struct snd_soc_component *component)
 380{
 381        return component->suspended;
 382}
 383
 384int snd_soc_component_probe(struct snd_soc_component *component)
 385{
 386        if (component->driver->probe)
 387                return component->driver->probe(component);
 388
 389        return 0;
 390}
 391
 392void snd_soc_component_remove(struct snd_soc_component *component)
 393{
 394        if (component->driver->remove)
 395                component->driver->remove(component);
 396}
 397
 398int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
 399                                      struct device_node *ep)
 400{
 401        if (component->driver->of_xlate_dai_id)
 402                return component->driver->of_xlate_dai_id(component, ep);
 403
 404        return -ENOTSUPP;
 405}
 406
 407int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
 408                                        struct of_phandle_args *args,
 409                                        const char **dai_name)
 410{
 411        if (component->driver->of_xlate_dai_name)
 412                return component->driver->of_xlate_dai_name(component,
 413                                                     args, dai_name);
 414        return -ENOTSUPP;
 415}
 416
 417int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
 418{
 419        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 420        struct snd_soc_component *component;
 421        int i;
 422
 423        /* FIXME: use 1st pointer */
 424        for_each_rtd_components(rtd, i, component)
 425                if (component->driver->pointer)
 426                        return component->driver->pointer(component, substream);
 427
 428        return 0;
 429}
 430
 431int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
 432                                unsigned int cmd, void *arg)
 433{
 434        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 435        struct snd_soc_component *component;
 436        int i;
 437
 438        /* FIXME: use 1st ioctl */
 439        for_each_rtd_components(rtd, i, component)
 440                if (component->driver->ioctl)
 441                        return component->driver->ioctl(component, substream,
 442                                                        cmd, arg);
 443
 444        return snd_pcm_lib_ioctl(substream, cmd, arg);
 445}
 446
 447int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
 448{
 449        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 450        struct snd_soc_component *component;
 451        int i, ret;
 452
 453        for_each_rtd_components(rtd, i, component) {
 454                if (component->driver->sync_stop) {
 455                        ret = component->driver->sync_stop(component,
 456                                                           substream);
 457                        if (ret < 0)
 458                                return ret;
 459                }
 460        }
 461
 462        return 0;
 463}
 464
 465int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
 466                                    int channel, unsigned long pos,
 467                                    void __user *buf, unsigned long bytes)
 468{
 469        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 470        struct snd_soc_component *component;
 471        int i;
 472
 473        /* FIXME. it returns 1st copy now */
 474        for_each_rtd_components(rtd, i, component)
 475                if (component->driver->copy_user)
 476                        return component->driver->copy_user(
 477                                component, substream, channel, pos, buf, bytes);
 478
 479        return -EINVAL;
 480}
 481
 482struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
 483                                        unsigned long offset)
 484{
 485        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 486        struct snd_soc_component *component;
 487        struct page *page;
 488        int i;
 489
 490        /* FIXME. it returns 1st page now */
 491        for_each_rtd_components(rtd, i, component) {
 492                if (component->driver->page) {
 493                        page = component->driver->page(component,
 494                                                       substream, offset);
 495                        if (page)
 496                                return page;
 497                }
 498        }
 499
 500        return NULL;
 501}
 502
 503int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
 504                               struct vm_area_struct *vma)
 505{
 506        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 507        struct snd_soc_component *component;
 508        int i;
 509
 510        /* FIXME. it returns 1st mmap now */
 511        for_each_rtd_components(rtd, i, component)
 512                if (component->driver->mmap)
 513                        return component->driver->mmap(component,
 514                                                       substream, vma);
 515
 516        return -EINVAL;
 517}
 518
 519int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
 520{
 521        struct snd_soc_component *component;
 522        int ret;
 523        int i;
 524
 525        for_each_rtd_components(rtd, i, component) {
 526                if (component->driver->pcm_construct) {
 527                        ret = component->driver->pcm_construct(component, rtd);
 528                        if (ret < 0)
 529                                return ret;
 530                }
 531        }
 532
 533        return 0;
 534}
 535
 536void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
 537{
 538        struct snd_soc_component *component;
 539        int i;
 540
 541        if (!rtd->pcm)
 542                return;
 543
 544        for_each_rtd_components(rtd, i, component)
 545                if (component->driver->pcm_destruct)
 546                        component->driver->pcm_destruct(component, rtd->pcm);
 547}
 548