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->ops &&
 318            component->driver->ops->open)
 319                return component->driver->ops->open(substream);
 320
 321        return 0;
 322}
 323
 324int snd_soc_component_close(struct snd_soc_component *component,
 325                            struct snd_pcm_substream *substream)
 326{
 327        if (component->driver->ops &&
 328            component->driver->ops->close)
 329                return component->driver->ops->close(substream);
 330
 331        return 0;
 332}
 333
 334int snd_soc_component_prepare(struct snd_soc_component *component,
 335                              struct snd_pcm_substream *substream)
 336{
 337        if (component->driver->ops &&
 338            component->driver->ops->prepare)
 339                return component->driver->ops->prepare(substream);
 340
 341        return 0;
 342}
 343
 344int snd_soc_component_hw_params(struct snd_soc_component *component,
 345                                struct snd_pcm_substream *substream,
 346                                struct snd_pcm_hw_params *params)
 347{
 348        if (component->driver->ops &&
 349            component->driver->ops->hw_params)
 350                return component->driver->ops->hw_params(substream, params);
 351
 352        return 0;
 353}
 354
 355int snd_soc_component_hw_free(struct snd_soc_component *component,
 356                               struct snd_pcm_substream *substream)
 357{
 358        if (component->driver->ops &&
 359            component->driver->ops->hw_free)
 360                return component->driver->ops->hw_free(substream);
 361
 362        return 0;
 363}
 364
 365int snd_soc_component_trigger(struct snd_soc_component *component,
 366                              struct snd_pcm_substream *substream,
 367                              int cmd)
 368{
 369        if (component->driver->ops &&
 370            component->driver->ops->trigger)
 371                return component->driver->ops->trigger(substream, cmd);
 372
 373        return 0;
 374}
 375
 376void snd_soc_component_suspend(struct snd_soc_component *component)
 377{
 378        if (component->driver->suspend)
 379                component->driver->suspend(component);
 380        component->suspended = 1;
 381}
 382
 383void snd_soc_component_resume(struct snd_soc_component *component)
 384{
 385        if (component->driver->resume)
 386                component->driver->resume(component);
 387        component->suspended = 0;
 388}
 389
 390int snd_soc_component_is_suspended(struct snd_soc_component *component)
 391{
 392        return component->suspended;
 393}
 394
 395int snd_soc_component_probe(struct snd_soc_component *component)
 396{
 397        if (component->driver->probe)
 398                return component->driver->probe(component);
 399
 400        return 0;
 401}
 402
 403void snd_soc_component_remove(struct snd_soc_component *component)
 404{
 405        if (component->driver->remove)
 406                component->driver->remove(component);
 407}
 408
 409int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
 410                                      struct device_node *ep)
 411{
 412        if (component->driver->of_xlate_dai_id)
 413                return component->driver->of_xlate_dai_id(component, ep);
 414
 415        return -ENOTSUPP;
 416}
 417
 418int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
 419                                        struct of_phandle_args *args,
 420                                        const char **dai_name)
 421{
 422        if (component->driver->of_xlate_dai_name)
 423                return component->driver->of_xlate_dai_name(component,
 424                                                     args, dai_name);
 425        return -ENOTSUPP;
 426}
 427
 428int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
 429{
 430        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 431        struct snd_soc_component *component;
 432        struct snd_soc_rtdcom_list *rtdcom;
 433
 434        for_each_rtdcom(rtd, rtdcom) {
 435                component = rtdcom->component;
 436
 437                /* FIXME: use 1st pointer */
 438                if (component->driver->ops &&
 439                    component->driver->ops->pointer)
 440                        return component->driver->ops->pointer(substream);
 441        }
 442
 443        return 0;
 444}
 445
 446int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
 447                                unsigned int cmd, void *arg)
 448{
 449        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 450        struct snd_soc_component *component;
 451        struct snd_soc_rtdcom_list *rtdcom;
 452
 453        for_each_rtdcom(rtd, rtdcom) {
 454                component = rtdcom->component;
 455
 456                /* FIXME: use 1st ioctl */
 457                if (component->driver->ops &&
 458                    component->driver->ops->ioctl)
 459                        return component->driver->ops->ioctl(substream,
 460                                                             cmd, arg);
 461        }
 462
 463        return snd_pcm_lib_ioctl(substream, cmd, arg);
 464}
 465
 466int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
 467                                    int channel, unsigned long pos,
 468                                    void __user *buf, unsigned long bytes)
 469{
 470        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 471        struct snd_soc_rtdcom_list *rtdcom;
 472        struct snd_soc_component *component;
 473
 474        for_each_rtdcom(rtd, rtdcom) {
 475                component = rtdcom->component;
 476
 477                /* FIXME. it returns 1st copy now */
 478                if (component->driver->ops &&
 479                    component->driver->ops->copy_user)
 480                        return component->driver->ops->copy_user(
 481                                substream, channel, pos, buf, bytes);
 482        }
 483
 484        return -EINVAL;
 485}
 486
 487struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
 488                                        unsigned long offset)
 489{
 490        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 491        struct snd_soc_rtdcom_list *rtdcom;
 492        struct snd_soc_component *component;
 493        struct page *page;
 494
 495        for_each_rtdcom(rtd, rtdcom) {
 496                component = rtdcom->component;
 497
 498                /* FIXME. it returns 1st page now */
 499                if (component->driver->ops &&
 500                    component->driver->ops->page) {
 501                        page = component->driver->ops->page(substream, offset);
 502                        if (page)
 503                                return page;
 504                }
 505        }
 506
 507        return NULL;
 508}
 509
 510int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
 511                               struct vm_area_struct *vma)
 512{
 513        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 514        struct snd_soc_rtdcom_list *rtdcom;
 515        struct snd_soc_component *component;
 516
 517        for_each_rtdcom(rtd, rtdcom) {
 518                component = rtdcom->component;
 519
 520                /* FIXME. it returns 1st mmap now */
 521                if (component->driver->ops &&
 522                    component->driver->ops->mmap)
 523                        return component->driver->ops->mmap(substream, vma);
 524        }
 525
 526        return -EINVAL;
 527}
 528
 529int snd_soc_pcm_component_new(struct snd_pcm *pcm)
 530{
 531        struct snd_soc_pcm_runtime *rtd = pcm->private_data;
 532        struct snd_soc_rtdcom_list *rtdcom;
 533        struct snd_soc_component *component;
 534        int ret;
 535
 536        for_each_rtdcom(rtd, rtdcom) {
 537                component = rtdcom->component;
 538
 539                if (component->driver->pcm_new) {
 540                        ret = component->driver->pcm_new(rtd);
 541                        if (ret < 0)
 542                                return ret;
 543                }
 544        }
 545
 546        return 0;
 547}
 548
 549void snd_soc_pcm_component_free(struct snd_pcm *pcm)
 550{
 551        struct snd_soc_pcm_runtime *rtd = pcm->private_data;
 552        struct snd_soc_rtdcom_list *rtdcom;
 553        struct snd_soc_component *component;
 554
 555        for_each_rtdcom(rtd, rtdcom) {
 556                component = rtdcom->component;
 557
 558                if (component->driver->pcm_free)
 559                        component->driver->pcm_free(pcm);
 560        }
 561}
 562