LCOV - code coverage report
Current view: top level - sound/hda - hdac_device.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 381 0.0 %
Date: 2022-04-01 14:58:12 Functions: 0 34 0.0 %
Branches: 0 225 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /*
       3                 :            :  * HD-audio codec core device
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <linux/init.h>
       7                 :            : #include <linux/delay.h>
       8                 :            : #include <linux/device.h>
       9                 :            : #include <linux/slab.h>
      10                 :            : #include <linux/module.h>
      11                 :            : #include <linux/export.h>
      12                 :            : #include <linux/pm_runtime.h>
      13                 :            : #include <sound/hdaudio.h>
      14                 :            : #include <sound/hda_regmap.h>
      15                 :            : #include <sound/pcm.h>
      16                 :            : #include "local.h"
      17                 :            : 
      18                 :            : static void setup_fg_nodes(struct hdac_device *codec);
      19                 :            : static int get_codec_vendor_name(struct hdac_device *codec);
      20                 :            : 
      21                 :          0 : static void default_release(struct device *dev)
      22                 :            : {
      23                 :          0 :         snd_hdac_device_exit(container_of(dev, struct hdac_device, dev));
      24                 :          0 : }
      25                 :            : 
      26                 :            : /**
      27                 :            :  * snd_hdac_device_init - initialize the HD-audio codec base device
      28                 :            :  * @codec: device to initialize
      29                 :            :  * @bus: but to attach
      30                 :            :  * @name: device name string
      31                 :            :  * @addr: codec address
      32                 :            :  *
      33                 :            :  * Returns zero for success or a negative error code.
      34                 :            :  *
      35                 :            :  * This function increments the runtime PM counter and marks it active.
      36                 :            :  * The caller needs to turn it off appropriately later.
      37                 :            :  *
      38                 :            :  * The caller needs to set the device's release op properly by itself.
      39                 :            :  */
      40                 :          0 : int snd_hdac_device_init(struct hdac_device *codec, struct hdac_bus *bus,
      41                 :            :                          const char *name, unsigned int addr)
      42                 :            : {
      43                 :          0 :         struct device *dev;
      44                 :          0 :         hda_nid_t fg;
      45                 :          0 :         int err;
      46                 :            : 
      47                 :          0 :         dev = &codec->dev;
      48                 :          0 :         device_initialize(dev);
      49                 :          0 :         dev->parent = bus->dev;
      50                 :          0 :         dev->bus = &snd_hda_bus_type;
      51                 :          0 :         dev->release = default_release;
      52                 :          0 :         dev->groups = hdac_dev_attr_groups;
      53                 :          0 :         dev_set_name(dev, "%s", name);
      54         [ #  # ]:          0 :         device_enable_async_suspend(dev);
      55                 :            : 
      56                 :          0 :         codec->bus = bus;
      57                 :          0 :         codec->addr = addr;
      58                 :          0 :         codec->type = HDA_DEV_CORE;
      59                 :          0 :         mutex_init(&codec->widget_lock);
      60                 :          0 :         mutex_init(&codec->regmap_lock);
      61                 :          0 :         pm_runtime_set_active(&codec->dev);
      62                 :          0 :         pm_runtime_get_noresume(&codec->dev);
      63                 :          0 :         atomic_set(&codec->in_pm, 0);
      64                 :            : 
      65                 :          0 :         err = snd_hdac_bus_add_device(bus, codec);
      66         [ #  # ]:          0 :         if (err < 0)
      67                 :          0 :                 goto error;
      68                 :            : 
      69                 :            :         /* fill parameters */
      70                 :          0 :         codec->vendor_id = snd_hdac_read_parm(codec, AC_NODE_ROOT,
      71                 :            :                                               AC_PAR_VENDOR_ID);
      72         [ #  # ]:          0 :         if (codec->vendor_id == -1) {
      73                 :            :                 /* read again, hopefully the access method was corrected
      74                 :            :                  * in the last read...
      75                 :            :                  */
      76                 :          0 :                 codec->vendor_id = snd_hdac_read_parm(codec, AC_NODE_ROOT,
      77                 :            :                                                       AC_PAR_VENDOR_ID);
      78                 :            :         }
      79                 :            : 
      80                 :          0 :         codec->subsystem_id = snd_hdac_read_parm(codec, AC_NODE_ROOT,
      81                 :            :                                                  AC_PAR_SUBSYSTEM_ID);
      82                 :          0 :         codec->revision_id = snd_hdac_read_parm(codec, AC_NODE_ROOT,
      83                 :            :                                                 AC_PAR_REV_ID);
      84                 :            : 
      85                 :          0 :         setup_fg_nodes(codec);
      86         [ #  # ]:          0 :         if (!codec->afg && !codec->mfg) {
      87                 :          0 :                 dev_err(dev, "no AFG or MFG node found\n");
      88                 :          0 :                 err = -ENODEV;
      89                 :          0 :                 goto error;
      90                 :            :         }
      91                 :            : 
      92         [ #  # ]:          0 :         fg = codec->afg ? codec->afg : codec->mfg;
      93                 :            : 
      94                 :          0 :         err = snd_hdac_refresh_widgets(codec);
      95         [ #  # ]:          0 :         if (err < 0)
      96                 :          0 :                 goto error;
      97                 :            : 
      98                 :          0 :         codec->power_caps = snd_hdac_read_parm(codec, fg, AC_PAR_POWER_STATE);
      99                 :            :         /* reread ssid if not set by parameter */
     100         [ #  # ]:          0 :         if (codec->subsystem_id == -1 || codec->subsystem_id == 0)
     101                 :          0 :                 snd_hdac_read(codec, fg, AC_VERB_GET_SUBSYSTEM_ID, 0,
     102                 :            :                               &codec->subsystem_id);
     103                 :            : 
     104                 :          0 :         err = get_codec_vendor_name(codec);
     105         [ #  # ]:          0 :         if (err < 0)
     106                 :          0 :                 goto error;
     107                 :            : 
     108                 :          0 :         codec->chip_name = kasprintf(GFP_KERNEL, "ID %x",
     109                 :          0 :                                      codec->vendor_id & 0xffff);
     110         [ #  # ]:          0 :         if (!codec->chip_name) {
     111                 :          0 :                 err = -ENOMEM;
     112                 :          0 :                 goto error;
     113                 :            :         }
     114                 :            : 
     115                 :            :         return 0;
     116                 :            : 
     117                 :          0 :  error:
     118                 :          0 :         put_device(&codec->dev);
     119                 :          0 :         return err;
     120                 :            : }
     121                 :            : EXPORT_SYMBOL_GPL(snd_hdac_device_init);
     122                 :            : 
     123                 :            : /**
     124                 :            :  * snd_hdac_device_exit - clean up the HD-audio codec base device
     125                 :            :  * @codec: device to clean up
     126                 :            :  */
     127                 :          0 : void snd_hdac_device_exit(struct hdac_device *codec)
     128                 :            : {
     129                 :          0 :         pm_runtime_put_noidle(&codec->dev);
     130                 :          0 :         snd_hdac_bus_remove_device(codec->bus, codec);
     131                 :          0 :         kfree(codec->vendor_name);
     132                 :          0 :         kfree(codec->chip_name);
     133                 :          0 : }
     134                 :            : EXPORT_SYMBOL_GPL(snd_hdac_device_exit);
     135                 :            : 
     136                 :            : /**
     137                 :            :  * snd_hdac_device_register - register the hd-audio codec base device
     138                 :            :  * @codec: the device to register
     139                 :            :  */
     140                 :          0 : int snd_hdac_device_register(struct hdac_device *codec)
     141                 :            : {
     142                 :          0 :         int err;
     143                 :            : 
     144                 :          0 :         err = device_add(&codec->dev);
     145         [ #  # ]:          0 :         if (err < 0)
     146                 :            :                 return err;
     147                 :          0 :         mutex_lock(&codec->widget_lock);
     148                 :          0 :         err = hda_widget_sysfs_init(codec);
     149                 :          0 :         mutex_unlock(&codec->widget_lock);
     150         [ #  # ]:          0 :         if (err < 0) {
     151                 :          0 :                 device_del(&codec->dev);
     152                 :          0 :                 return err;
     153                 :            :         }
     154                 :            : 
     155                 :            :         return 0;
     156                 :            : }
     157                 :            : EXPORT_SYMBOL_GPL(snd_hdac_device_register);
     158                 :            : 
     159                 :            : /**
     160                 :            :  * snd_hdac_device_unregister - unregister the hd-audio codec base device
     161                 :            :  * @codec: the device to unregister
     162                 :            :  */
     163                 :          0 : void snd_hdac_device_unregister(struct hdac_device *codec)
     164                 :            : {
     165         [ #  # ]:          0 :         if (device_is_registered(&codec->dev)) {
     166                 :          0 :                 mutex_lock(&codec->widget_lock);
     167                 :          0 :                 hda_widget_sysfs_exit(codec);
     168                 :          0 :                 mutex_unlock(&codec->widget_lock);
     169                 :          0 :                 device_del(&codec->dev);
     170                 :          0 :                 snd_hdac_bus_remove_device(codec->bus, codec);
     171                 :            :         }
     172                 :          0 : }
     173                 :            : EXPORT_SYMBOL_GPL(snd_hdac_device_unregister);
     174                 :            : 
     175                 :            : /**
     176                 :            :  * snd_hdac_device_set_chip_name - set/update the codec name
     177                 :            :  * @codec: the HDAC device
     178                 :            :  * @name: name string to set
     179                 :            :  *
     180                 :            :  * Returns 0 if the name is set or updated, or a negative error code.
     181                 :            :  */
     182                 :          0 : int snd_hdac_device_set_chip_name(struct hdac_device *codec, const char *name)
     183                 :            : {
     184                 :          0 :         char *newname;
     185                 :            : 
     186         [ #  # ]:          0 :         if (!name)
     187                 :            :                 return 0;
     188                 :          0 :         newname = kstrdup(name, GFP_KERNEL);
     189         [ #  # ]:          0 :         if (!newname)
     190                 :            :                 return -ENOMEM;
     191                 :          0 :         kfree(codec->chip_name);
     192                 :          0 :         codec->chip_name = newname;
     193                 :          0 :         return 0;
     194                 :            : }
     195                 :            : EXPORT_SYMBOL_GPL(snd_hdac_device_set_chip_name);
     196                 :            : 
     197                 :            : /**
     198                 :            :  * snd_hdac_codec_modalias - give the module alias name
     199                 :            :  * @codec: HDAC device
     200                 :            :  * @buf: string buffer to store
     201                 :            :  * @size: string buffer size
     202                 :            :  *
     203                 :            :  * Returns the size of string, like snprintf(), or a negative error code.
     204                 :            :  */
     205                 :          0 : int snd_hdac_codec_modalias(struct hdac_device *codec, char *buf, size_t size)
     206                 :            : {
     207                 :          0 :         return snprintf(buf, size, "hdaudio:v%08Xr%08Xa%02X\n",
     208                 :            :                         codec->vendor_id, codec->revision_id, codec->type);
     209                 :            : }
     210                 :            : EXPORT_SYMBOL_GPL(snd_hdac_codec_modalias);
     211                 :            : 
     212                 :            : /**
     213                 :            :  * snd_hdac_make_cmd - compose a 32bit command word to be sent to the
     214                 :            :  *      HD-audio controller
     215                 :            :  * @codec: the codec object
     216                 :            :  * @nid: NID to encode
     217                 :            :  * @verb: verb to encode
     218                 :            :  * @parm: parameter to encode
     219                 :            :  *
     220                 :            :  * Return an encoded command verb or -1 for error.
     221                 :            :  */
     222                 :          0 : static unsigned int snd_hdac_make_cmd(struct hdac_device *codec, hda_nid_t nid,
     223                 :            :                                       unsigned int verb, unsigned int parm)
     224                 :            : {
     225                 :          0 :         u32 val, addr;
     226                 :            : 
     227                 :          0 :         addr = codec->addr;
     228   [ #  #  #  # ]:          0 :         if ((addr & ~0xf) || (nid & ~0x7f) ||
     229   [ #  #  #  # ]:          0 :             (verb & ~0xfff) || (parm & ~0xffff)) {
     230                 :          0 :                 dev_err(&codec->dev, "out of range cmd %x:%x:%x:%x\n",
     231                 :            :                         addr, nid, verb, parm);
     232                 :          0 :                 return -1;
     233                 :            :         }
     234                 :            : 
     235                 :          0 :         val = addr << 28;
     236                 :          0 :         val |= (u32)nid << 20;
     237                 :          0 :         val |= verb << 8;
     238                 :          0 :         val |= parm;
     239                 :          0 :         return val;
     240                 :            : }
     241                 :            : 
     242                 :            : /**
     243                 :            :  * snd_hdac_exec_verb - execute an encoded verb
     244                 :            :  * @codec: the codec object
     245                 :            :  * @cmd: encoded verb to execute
     246                 :            :  * @flags: optional flags, pass zero for default
     247                 :            :  * @res: the pointer to store the result, NULL if running async
     248                 :            :  *
     249                 :            :  * Returns zero if successful, or a negative error code.
     250                 :            :  *
     251                 :            :  * This calls the exec_verb op when set in hdac_codec.  If not,
     252                 :            :  * call the default snd_hdac_bus_exec_verb().
     253                 :            :  */
     254                 :          0 : int snd_hdac_exec_verb(struct hdac_device *codec, unsigned int cmd,
     255                 :            :                        unsigned int flags, unsigned int *res)
     256                 :            : {
     257         [ #  # ]:          0 :         if (codec->exec_verb)
     258                 :          0 :                 return codec->exec_verb(codec, cmd, flags, res);
     259                 :          0 :         return snd_hdac_bus_exec_verb(codec->bus, codec->addr, cmd, res);
     260                 :            : }
     261                 :            : 
     262                 :            : 
     263                 :            : /**
     264                 :            :  * snd_hdac_read - execute a verb
     265                 :            :  * @codec: the codec object
     266                 :            :  * @nid: NID to execute a verb
     267                 :            :  * @verb: verb to execute
     268                 :            :  * @parm: parameter for a verb
     269                 :            :  * @res: the pointer to store the result, NULL if running async
     270                 :            :  *
     271                 :            :  * Returns zero if successful, or a negative error code.
     272                 :            :  */
     273                 :          0 : int snd_hdac_read(struct hdac_device *codec, hda_nid_t nid,
     274                 :            :                   unsigned int verb, unsigned int parm, unsigned int *res)
     275                 :            : {
     276                 :          0 :         unsigned int cmd = snd_hdac_make_cmd(codec, nid, verb, parm);
     277                 :            : 
     278                 :          0 :         return snd_hdac_exec_verb(codec, cmd, 0, res);
     279                 :            : }
     280                 :            : EXPORT_SYMBOL_GPL(snd_hdac_read);
     281                 :            : 
     282                 :            : /**
     283                 :            :  * _snd_hdac_read_parm - read a parmeter
     284                 :            :  * @codec: the codec object
     285                 :            :  * @nid: NID to read a parameter
     286                 :            :  * @parm: parameter to read
     287                 :            :  * @res: pointer to store the read value
     288                 :            :  *
     289                 :            :  * This function returns zero or an error unlike snd_hdac_read_parm().
     290                 :            :  */
     291                 :          0 : int _snd_hdac_read_parm(struct hdac_device *codec, hda_nid_t nid, int parm,
     292                 :            :                         unsigned int *res)
     293                 :            : {
     294                 :          0 :         unsigned int cmd;
     295                 :            : 
     296                 :          0 :         cmd = snd_hdac_regmap_encode_verb(nid, AC_VERB_PARAMETERS) | parm;
     297                 :          0 :         return snd_hdac_regmap_read_raw(codec, cmd, res);
     298                 :            : }
     299                 :            : EXPORT_SYMBOL_GPL(_snd_hdac_read_parm);
     300                 :            : 
     301                 :            : /**
     302                 :            :  * snd_hdac_read_parm_uncached - read a codec parameter without caching
     303                 :            :  * @codec: the codec object
     304                 :            :  * @nid: NID to read a parameter
     305                 :            :  * @parm: parameter to read
     306                 :            :  *
     307                 :            :  * Returns -1 for error.  If you need to distinguish the error more
     308                 :            :  * strictly, use snd_hdac_read() directly.
     309                 :            :  */
     310                 :          0 : int snd_hdac_read_parm_uncached(struct hdac_device *codec, hda_nid_t nid,
     311                 :            :                                 int parm)
     312                 :            : {
     313                 :          0 :         unsigned int cmd, val;
     314                 :            : 
     315                 :          0 :         cmd = snd_hdac_regmap_encode_verb(nid, AC_VERB_PARAMETERS) | parm;
     316   [ #  #  #  # ]:          0 :         if (snd_hdac_regmap_read_raw_uncached(codec, cmd, &val) < 0)
     317                 :            :                 return -1;
     318                 :          0 :         return val;
     319                 :            : }
     320                 :            : EXPORT_SYMBOL_GPL(snd_hdac_read_parm_uncached);
     321                 :            : 
     322                 :            : /**
     323                 :            :  * snd_hdac_override_parm - override read-only parameters
     324                 :            :  * @codec: the codec object
     325                 :            :  * @nid: NID for the parameter
     326                 :            :  * @parm: the parameter to change
     327                 :            :  * @val: the parameter value to overwrite
     328                 :            :  */
     329                 :          0 : int snd_hdac_override_parm(struct hdac_device *codec, hda_nid_t nid,
     330                 :            :                            unsigned int parm, unsigned int val)
     331                 :            : {
     332                 :          0 :         unsigned int verb = (AC_VERB_PARAMETERS << 8) | (nid << 20) | parm;
     333                 :          0 :         int err;
     334                 :            : 
     335         [ #  # ]:          0 :         if (!codec->regmap)
     336                 :            :                 return -EINVAL;
     337                 :            : 
     338                 :          0 :         codec->caps_overwriting = true;
     339                 :          0 :         err = snd_hdac_regmap_write_raw(codec, verb, val);
     340                 :          0 :         codec->caps_overwriting = false;
     341                 :          0 :         return err;
     342                 :            : }
     343                 :            : EXPORT_SYMBOL_GPL(snd_hdac_override_parm);
     344                 :            : 
     345                 :            : /**
     346                 :            :  * snd_hdac_get_sub_nodes - get start NID and number of subtree nodes
     347                 :            :  * @codec: the codec object
     348                 :            :  * @nid: NID to inspect
     349                 :            :  * @start_id: the pointer to store the starting NID
     350                 :            :  *
     351                 :            :  * Returns the number of subtree nodes or zero if not found.
     352                 :            :  * This function reads parameters always without caching.
     353                 :            :  */
     354                 :          0 : int snd_hdac_get_sub_nodes(struct hdac_device *codec, hda_nid_t nid,
     355                 :            :                            hda_nid_t *start_id)
     356                 :            : {
     357                 :          0 :         unsigned int parm;
     358                 :            : 
     359                 :          0 :         parm = snd_hdac_read_parm_uncached(codec, nid, AC_PAR_NODE_COUNT);
     360         [ #  # ]:          0 :         if (parm == -1) {
     361                 :          0 :                 *start_id = 0;
     362                 :          0 :                 return 0;
     363                 :            :         }
     364                 :          0 :         *start_id = (parm >> 16) & 0x7fff;
     365                 :          0 :         return (int)(parm & 0x7fff);
     366                 :            : }
     367                 :            : EXPORT_SYMBOL_GPL(snd_hdac_get_sub_nodes);
     368                 :            : 
     369                 :            : /*
     370                 :            :  * look for an AFG and MFG nodes
     371                 :            :  */
     372                 :          0 : static void setup_fg_nodes(struct hdac_device *codec)
     373                 :            : {
     374                 :          0 :         int i, total_nodes, function_id;
     375                 :          0 :         hda_nid_t nid;
     376                 :            : 
     377                 :          0 :         total_nodes = snd_hdac_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
     378         [ #  # ]:          0 :         for (i = 0; i < total_nodes; i++, nid++) {
     379                 :          0 :                 function_id = snd_hdac_read_parm(codec, nid,
     380                 :            :                                                  AC_PAR_FUNCTION_TYPE);
     381      [ #  #  # ]:          0 :                 switch (function_id & 0xff) {
     382                 :          0 :                 case AC_GRP_AUDIO_FUNCTION:
     383                 :          0 :                         codec->afg = nid;
     384                 :          0 :                         codec->afg_function_id = function_id & 0xff;
     385                 :          0 :                         codec->afg_unsol = (function_id >> 8) & 1;
     386                 :          0 :                         break;
     387                 :          0 :                 case AC_GRP_MODEM_FUNCTION:
     388                 :          0 :                         codec->mfg = nid;
     389                 :          0 :                         codec->mfg_function_id = function_id & 0xff;
     390                 :          0 :                         codec->mfg_unsol = (function_id >> 8) & 1;
     391                 :          0 :                         break;
     392                 :            :                 default:
     393                 :            :                         break;
     394                 :            :                 }
     395                 :            :         }
     396                 :          0 : }
     397                 :            : 
     398                 :            : /**
     399                 :            :  * snd_hdac_refresh_widgets - Reset the widget start/end nodes
     400                 :            :  * @codec: the codec object
     401                 :            :  */
     402                 :          0 : int snd_hdac_refresh_widgets(struct hdac_device *codec)
     403                 :            : {
     404                 :          0 :         hda_nid_t start_nid;
     405                 :          0 :         int nums, err = 0;
     406                 :            : 
     407                 :            :         /*
     408                 :            :          * Serialize against multiple threads trying to update the sysfs
     409                 :            :          * widgets array.
     410                 :            :          */
     411                 :          0 :         mutex_lock(&codec->widget_lock);
     412                 :          0 :         nums = snd_hdac_get_sub_nodes(codec, codec->afg, &start_nid);
     413   [ #  #  #  # ]:          0 :         if (!start_nid || nums <= 0 || nums >= 0xff) {
     414                 :          0 :                 dev_err(&codec->dev, "cannot read sub nodes for FG 0x%02x\n",
     415                 :            :                         codec->afg);
     416                 :          0 :                 err = -EINVAL;
     417                 :          0 :                 goto unlock;
     418                 :            :         }
     419                 :            : 
     420                 :          0 :         err = hda_widget_sysfs_reinit(codec, start_nid, nums);
     421         [ #  # ]:          0 :         if (err < 0)
     422                 :          0 :                 goto unlock;
     423                 :            : 
     424                 :          0 :         codec->num_nodes = nums;
     425                 :          0 :         codec->start_nid = start_nid;
     426                 :          0 :         codec->end_nid = start_nid + nums;
     427                 :          0 : unlock:
     428                 :          0 :         mutex_unlock(&codec->widget_lock);
     429                 :          0 :         return err;
     430                 :            : }
     431                 :            : EXPORT_SYMBOL_GPL(snd_hdac_refresh_widgets);
     432                 :            : 
     433                 :            : /* return CONNLIST_LEN parameter of the given widget */
     434                 :          0 : static unsigned int get_num_conns(struct hdac_device *codec, hda_nid_t nid)
     435                 :            : {
     436                 :          0 :         unsigned int wcaps = get_wcaps(codec, nid);
     437                 :          0 :         unsigned int parm;
     438                 :            : 
     439   [ #  #  #  # ]:          0 :         if (!(wcaps & AC_WCAP_CONN_LIST) &&
     440                 :            :             get_wcaps_type(wcaps) != AC_WID_VOL_KNB)
     441                 :            :                 return 0;
     442                 :            : 
     443                 :          0 :         parm = snd_hdac_read_parm(codec, nid, AC_PAR_CONNLIST_LEN);
     444         [ #  # ]:          0 :         if (parm == -1)
     445                 :          0 :                 parm = 0;
     446                 :            :         return parm;
     447                 :            : }
     448                 :            : 
     449                 :            : /**
     450                 :            :  * snd_hdac_get_connections - get a widget connection list
     451                 :            :  * @codec: the codec object
     452                 :            :  * @nid: NID
     453                 :            :  * @conn_list: the array to store the results, can be NULL
     454                 :            :  * @max_conns: the max size of the given array
     455                 :            :  *
     456                 :            :  * Returns the number of connected widgets, zero for no connection, or a
     457                 :            :  * negative error code.  When the number of elements don't fit with the
     458                 :            :  * given array size, it returns -ENOSPC.
     459                 :            :  *
     460                 :            :  * When @conn_list is NULL, it just checks the number of connections.
     461                 :            :  */
     462                 :          0 : int snd_hdac_get_connections(struct hdac_device *codec, hda_nid_t nid,
     463                 :            :                              hda_nid_t *conn_list, int max_conns)
     464                 :            : {
     465                 :          0 :         unsigned int parm;
     466                 :          0 :         int i, conn_len, conns, err;
     467                 :          0 :         unsigned int shift, num_elems, mask;
     468                 :          0 :         hda_nid_t prev_nid;
     469                 :          0 :         int null_count = 0;
     470                 :            : 
     471                 :          0 :         parm = get_num_conns(codec, nid);
     472         [ #  # ]:          0 :         if (!parm)
     473                 :            :                 return 0;
     474                 :            : 
     475         [ #  # ]:          0 :         if (parm & AC_CLIST_LONG) {
     476                 :            :                 /* long form */
     477                 :            :                 shift = 16;
     478                 :            :                 num_elems = 2;
     479                 :            :         } else {
     480                 :            :                 /* short form */
     481                 :          0 :                 shift = 8;
     482                 :          0 :                 num_elems = 4;
     483                 :            :         }
     484                 :          0 :         conn_len = parm & AC_CLIST_LENGTH;
     485                 :          0 :         mask = (1 << (shift-1)) - 1;
     486                 :            : 
     487         [ #  # ]:          0 :         if (!conn_len)
     488                 :            :                 return 0; /* no connection */
     489                 :            : 
     490         [ #  # ]:          0 :         if (conn_len == 1) {
     491                 :            :                 /* single connection */
     492                 :          0 :                 err = snd_hdac_read(codec, nid, AC_VERB_GET_CONNECT_LIST, 0,
     493                 :            :                                     &parm);
     494         [ #  # ]:          0 :                 if (err < 0)
     495                 :            :                         return err;
     496         [ #  # ]:          0 :                 if (conn_list)
     497                 :          0 :                         conn_list[0] = parm & mask;
     498                 :          0 :                 return 1;
     499                 :            :         }
     500                 :            : 
     501                 :            :         /* multi connection */
     502                 :            :         conns = 0;
     503                 :            :         prev_nid = 0;
     504         [ #  # ]:          0 :         for (i = 0; i < conn_len; i++) {
     505                 :          0 :                 int range_val;
     506                 :          0 :                 hda_nid_t val, n;
     507                 :            : 
     508         [ #  # ]:          0 :                 if (i % num_elems == 0) {
     509                 :          0 :                         err = snd_hdac_read(codec, nid,
     510                 :            :                                             AC_VERB_GET_CONNECT_LIST, i,
     511                 :            :                                             &parm);
     512         [ #  # ]:          0 :                         if (err < 0)
     513                 :            :                                 return -EIO;
     514                 :            :                 }
     515                 :          0 :                 range_val = !!(parm & (1 << (shift-1))); /* ranges */
     516                 :          0 :                 val = parm & mask;
     517   [ #  #  #  # ]:          0 :                 if (val == 0 && null_count++) {  /* no second chance */
     518                 :            :                         dev_dbg(&codec->dev,
     519                 :            :                                 "invalid CONNECT_LIST verb %x[%i]:%x\n",
     520                 :            :                                 nid, i, parm);
     521                 :            :                         return 0;
     522                 :            :                 }
     523                 :          0 :                 parm >>= shift;
     524         [ #  # ]:          0 :                 if (range_val) {
     525                 :            :                         /* ranges between the previous and this one */
     526         [ #  # ]:          0 :                         if (!prev_nid || prev_nid >= val) {
     527                 :          0 :                                 dev_warn(&codec->dev,
     528                 :            :                                          "invalid dep_range_val %x:%x\n",
     529                 :            :                                          prev_nid, val);
     530                 :          0 :                                 continue;
     531                 :            :                         }
     532         [ #  # ]:          0 :                         for (n = prev_nid + 1; n <= val; n++) {
     533         [ #  # ]:          0 :                                 if (conn_list) {
     534         [ #  # ]:          0 :                                         if (conns >= max_conns)
     535                 :            :                                                 return -ENOSPC;
     536                 :          0 :                                         conn_list[conns] = n;
     537                 :            :                                 }
     538                 :          0 :                                 conns++;
     539                 :            :                         }
     540                 :            :                 } else {
     541         [ #  # ]:          0 :                         if (conn_list) {
     542         [ #  # ]:          0 :                                 if (conns >= max_conns)
     543                 :            :                                         return -ENOSPC;
     544                 :          0 :                                 conn_list[conns] = val;
     545                 :            :                         }
     546                 :          0 :                         conns++;
     547                 :            :                 }
     548                 :            :                 prev_nid = val;
     549                 :            :         }
     550                 :            :         return conns;
     551                 :            : }
     552                 :            : EXPORT_SYMBOL_GPL(snd_hdac_get_connections);
     553                 :            : 
     554                 :            : #ifdef CONFIG_PM
     555                 :            : /**
     556                 :            :  * snd_hdac_power_up - power up the codec
     557                 :            :  * @codec: the codec object
     558                 :            :  *
     559                 :            :  * This function calls the runtime PM helper to power up the given codec.
     560                 :            :  * Unlike snd_hdac_power_up_pm(), you should call this only for the code
     561                 :            :  * path that isn't included in PM path.  Otherwise it gets stuck.
     562                 :            :  *
     563                 :            :  * Returns zero if successful, or a negative error code.
     564                 :            :  */
     565                 :          0 : int snd_hdac_power_up(struct hdac_device *codec)
     566                 :            : {
     567                 :          0 :         return pm_runtime_get_sync(&codec->dev);
     568                 :            : }
     569                 :            : EXPORT_SYMBOL_GPL(snd_hdac_power_up);
     570                 :            : 
     571                 :            : /**
     572                 :            :  * snd_hdac_power_down - power down the codec
     573                 :            :  * @codec: the codec object
     574                 :            :  *
     575                 :            :  * Returns zero if successful, or a negative error code.
     576                 :            :  */
     577                 :          0 : int snd_hdac_power_down(struct hdac_device *codec)
     578                 :            : {
     579                 :          0 :         struct device *dev = &codec->dev;
     580                 :            : 
     581                 :          0 :         pm_runtime_mark_last_busy(dev);
     582                 :          0 :         return pm_runtime_put_autosuspend(dev);
     583                 :            : }
     584                 :            : EXPORT_SYMBOL_GPL(snd_hdac_power_down);
     585                 :            : 
     586                 :            : /**
     587                 :            :  * snd_hdac_power_up_pm - power up the codec
     588                 :            :  * @codec: the codec object
     589                 :            :  *
     590                 :            :  * This function can be called in a recursive code path like init code
     591                 :            :  * which may be called by PM suspend/resume again.  OTOH, if a power-up
     592                 :            :  * call must wake up the sleeper (e.g. in a kctl callback), use
     593                 :            :  * snd_hdac_power_up() instead.
     594                 :            :  *
     595                 :            :  * Returns zero if successful, or a negative error code.
     596                 :            :  */
     597                 :          0 : int snd_hdac_power_up_pm(struct hdac_device *codec)
     598                 :            : {
     599         [ #  # ]:          0 :         if (!atomic_inc_not_zero(&codec->in_pm))
     600                 :          0 :                 return snd_hdac_power_up(codec);
     601                 :            :         return 0;
     602                 :            : }
     603                 :            : EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);
     604                 :            : 
     605                 :            : /* like snd_hdac_power_up_pm(), but only increment the pm count when
     606                 :            :  * already powered up.  Returns -1 if not powered up, 1 if incremented
     607                 :            :  * or 0 if unchanged.  Only used in hdac_regmap.c
     608                 :            :  */
     609                 :          0 : int snd_hdac_keep_power_up(struct hdac_device *codec)
     610                 :            : {
     611         [ #  # ]:          0 :         if (!atomic_inc_not_zero(&codec->in_pm)) {
     612                 :          0 :                 int ret = pm_runtime_get_if_in_use(&codec->dev);
     613         [ #  # ]:          0 :                 if (!ret)
     614                 :            :                         return -1;
     615         [ #  # ]:          0 :                 if (ret < 0)
     616                 :          0 :                         return 0;
     617                 :            :         }
     618                 :            :         return 1;
     619                 :            : }
     620                 :            : 
     621                 :            : /**
     622                 :            :  * snd_hdac_power_down_pm - power down the codec
     623                 :            :  * @codec: the codec object
     624                 :            :  *
     625                 :            :  * Like snd_hdac_power_up_pm(), this function is used in a recursive
     626                 :            :  * code path like init code which may be called by PM suspend/resume again.
     627                 :            :  *
     628                 :            :  * Returns zero if successful, or a negative error code.
     629                 :            :  */
     630                 :          0 : int snd_hdac_power_down_pm(struct hdac_device *codec)
     631                 :            : {
     632         [ #  # ]:          0 :         if (atomic_dec_if_positive(&codec->in_pm) < 0)
     633                 :          0 :                 return snd_hdac_power_down(codec);
     634                 :            :         return 0;
     635                 :            : }
     636                 :            : EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm);
     637                 :            : #endif
     638                 :            : 
     639                 :            : /* codec vendor labels */
     640                 :            : struct hda_vendor_id {
     641                 :            :         unsigned int id;
     642                 :            :         const char *name;
     643                 :            : };
     644                 :            : 
     645                 :            : static const struct hda_vendor_id hda_vendor_ids[] = {
     646                 :            :         { 0x1002, "ATI" },
     647                 :            :         { 0x1013, "Cirrus Logic" },
     648                 :            :         { 0x1057, "Motorola" },
     649                 :            :         { 0x1095, "Silicon Image" },
     650                 :            :         { 0x10de, "Nvidia" },
     651                 :            :         { 0x10ec, "Realtek" },
     652                 :            :         { 0x1102, "Creative" },
     653                 :            :         { 0x1106, "VIA" },
     654                 :            :         { 0x111d, "IDT" },
     655                 :            :         { 0x11c1, "LSI" },
     656                 :            :         { 0x11d4, "Analog Devices" },
     657                 :            :         { 0x13f6, "C-Media" },
     658                 :            :         { 0x14f1, "Conexant" },
     659                 :            :         { 0x17e8, "Chrontel" },
     660                 :            :         { 0x1854, "LG" },
     661                 :            :         { 0x1aec, "Wolfson Microelectronics" },
     662                 :            :         { 0x1af4, "QEMU" },
     663                 :            :         { 0x434d, "C-Media" },
     664                 :            :         { 0x8086, "Intel" },
     665                 :            :         { 0x8384, "SigmaTel" },
     666                 :            :         {} /* terminator */
     667                 :            : };
     668                 :            : 
     669                 :            : /* store the codec vendor name */
     670                 :            : static int get_codec_vendor_name(struct hdac_device *codec)
     671                 :            : {
     672                 :            :         const struct hda_vendor_id *c;
     673                 :            :         u16 vendor_id = codec->vendor_id >> 16;
     674                 :            : 
     675                 :            :         for (c = hda_vendor_ids; c->id; c++) {
     676                 :            :                 if (c->id == vendor_id) {
     677                 :            :                         codec->vendor_name = kstrdup(c->name, GFP_KERNEL);
     678                 :            :                         return codec->vendor_name ? 0 : -ENOMEM;
     679                 :            :                 }
     680                 :            :         }
     681                 :            : 
     682                 :            :         codec->vendor_name = kasprintf(GFP_KERNEL, "Generic %04x", vendor_id);
     683                 :            :         return codec->vendor_name ? 0 : -ENOMEM;
     684                 :            : }
     685                 :            : 
     686                 :            : /*
     687                 :            :  * stream formats
     688                 :            :  */
     689                 :            : struct hda_rate_tbl {
     690                 :            :         unsigned int hz;
     691                 :            :         unsigned int alsa_bits;
     692                 :            :         unsigned int hda_fmt;
     693                 :            : };
     694                 :            : 
     695                 :            : /* rate = base * mult / div */
     696                 :            : #define HDA_RATE(base, mult, div) \
     697                 :            :         (AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \
     698                 :            :          (((div) - 1) << AC_FMT_DIV_SHIFT))
     699                 :            : 
     700                 :            : static const struct hda_rate_tbl rate_bits[] = {
     701                 :            :         /* rate in Hz, ALSA rate bitmask, HDA format value */
     702                 :            : 
     703                 :            :         /* autodetected value used in snd_hda_query_supported_pcm */
     704                 :            :         { 8000, SNDRV_PCM_RATE_8000, HDA_RATE(48, 1, 6) },
     705                 :            :         { 11025, SNDRV_PCM_RATE_11025, HDA_RATE(44, 1, 4) },
     706                 :            :         { 16000, SNDRV_PCM_RATE_16000, HDA_RATE(48, 1, 3) },
     707                 :            :         { 22050, SNDRV_PCM_RATE_22050, HDA_RATE(44, 1, 2) },
     708                 :            :         { 32000, SNDRV_PCM_RATE_32000, HDA_RATE(48, 2, 3) },
     709                 :            :         { 44100, SNDRV_PCM_RATE_44100, HDA_RATE(44, 1, 1) },
     710                 :            :         { 48000, SNDRV_PCM_RATE_48000, HDA_RATE(48, 1, 1) },
     711                 :            :         { 88200, SNDRV_PCM_RATE_88200, HDA_RATE(44, 2, 1) },
     712                 :            :         { 96000, SNDRV_PCM_RATE_96000, HDA_RATE(48, 2, 1) },
     713                 :            :         { 176400, SNDRV_PCM_RATE_176400, HDA_RATE(44, 4, 1) },
     714                 :            :         { 192000, SNDRV_PCM_RATE_192000, HDA_RATE(48, 4, 1) },
     715                 :            : #define AC_PAR_PCM_RATE_BITS    11
     716                 :            :         /* up to bits 10, 384kHZ isn't supported properly */
     717                 :            : 
     718                 :            :         /* not autodetected value */
     719                 :            :         { 9600, SNDRV_PCM_RATE_KNOT, HDA_RATE(48, 1, 5) },
     720                 :            : 
     721                 :            :         { 0 } /* terminator */
     722                 :            : };
     723                 :            : 
     724                 :            : /**
     725                 :            :  * snd_hdac_calc_stream_format - calculate the format bitset
     726                 :            :  * @rate: the sample rate
     727                 :            :  * @channels: the number of channels
     728                 :            :  * @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
     729                 :            :  * @maxbps: the max. bps
     730                 :            :  * @spdif_ctls: HD-audio SPDIF status bits (0 if irrelevant)
     731                 :            :  *
     732                 :            :  * Calculate the format bitset from the given rate, channels and th PCM format.
     733                 :            :  *
     734                 :            :  * Return zero if invalid.
     735                 :            :  */
     736                 :          0 : unsigned int snd_hdac_calc_stream_format(unsigned int rate,
     737                 :            :                                          unsigned int channels,
     738                 :            :                                          snd_pcm_format_t format,
     739                 :            :                                          unsigned int maxbps,
     740                 :            :                                          unsigned short spdif_ctls)
     741                 :            : {
     742                 :          0 :         int i;
     743                 :          0 :         unsigned int val = 0;
     744                 :            : 
     745         [ #  # ]:          0 :         for (i = 0; rate_bits[i].hz; i++)
     746         [ #  # ]:          0 :                 if (rate_bits[i].hz == rate) {
     747                 :          0 :                         val = rate_bits[i].hda_fmt;
     748                 :          0 :                         break;
     749                 :            :                 }
     750         [ #  # ]:          0 :         if (!rate_bits[i].hz)
     751                 :            :                 return 0;
     752                 :            : 
     753         [ #  # ]:          0 :         if (channels == 0 || channels > 8)
     754                 :            :                 return 0;
     755                 :          0 :         val |= channels - 1;
     756                 :            : 
     757   [ #  #  #  # ]:          0 :         switch (snd_pcm_format_width(format)) {
     758                 :            :         case 8:
     759                 :            :                 val |= AC_FMT_BITS_8;
     760                 :            :                 break;
     761                 :          0 :         case 16:
     762                 :          0 :                 val |= AC_FMT_BITS_16;
     763                 :          0 :                 break;
     764                 :          0 :         case 20:
     765                 :            :         case 24:
     766                 :            :         case 32:
     767         [ #  # ]:          0 :                 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
     768                 :          0 :                         val |= AC_FMT_BITS_32;
     769         [ #  # ]:          0 :                 else if (maxbps >= 24)
     770                 :          0 :                         val |= AC_FMT_BITS_24;
     771                 :            :                 else
     772                 :          0 :                         val |= AC_FMT_BITS_20;
     773                 :            :                 break;
     774                 :            :         default:
     775                 :            :                 return 0;
     776                 :            :         }
     777                 :            : 
     778         [ #  # ]:          0 :         if (spdif_ctls & AC_DIG1_NONAUDIO)
     779                 :          0 :                 val |= AC_FMT_TYPE_NON_PCM;
     780                 :            : 
     781                 :            :         return val;
     782                 :            : }
     783                 :            : EXPORT_SYMBOL_GPL(snd_hdac_calc_stream_format);
     784                 :            : 
     785                 :          0 : static unsigned int query_pcm_param(struct hdac_device *codec, hda_nid_t nid)
     786                 :            : {
     787                 :          0 :         unsigned int val = 0;
     788                 :            : 
     789         [ #  # ]:          0 :         if (nid != codec->afg &&
     790         [ #  # ]:          0 :             (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD))
     791                 :          0 :                 val = snd_hdac_read_parm(codec, nid, AC_PAR_PCM);
     792         [ #  # ]:          0 :         if (!val || val == -1)
     793                 :          0 :                 val = snd_hdac_read_parm(codec, codec->afg, AC_PAR_PCM);
     794         [ #  # ]:          0 :         if (!val || val == -1)
     795                 :          0 :                 return 0;
     796                 :            :         return val;
     797                 :            : }
     798                 :            : 
     799                 :          0 : static unsigned int query_stream_param(struct hdac_device *codec, hda_nid_t nid)
     800                 :            : {
     801                 :          0 :         unsigned int streams = snd_hdac_read_parm(codec, nid, AC_PAR_STREAM);
     802                 :            : 
     803         [ #  # ]:          0 :         if (!streams || streams == -1)
     804                 :          0 :                 streams = snd_hdac_read_parm(codec, codec->afg, AC_PAR_STREAM);
     805         [ #  # ]:          0 :         if (!streams || streams == -1)
     806                 :          0 :                 return 0;
     807                 :            :         return streams;
     808                 :            : }
     809                 :            : 
     810                 :            : /**
     811                 :            :  * snd_hdac_query_supported_pcm - query the supported PCM rates and formats
     812                 :            :  * @codec: the codec object
     813                 :            :  * @nid: NID to query
     814                 :            :  * @ratesp: the pointer to store the detected rate bitflags
     815                 :            :  * @formatsp: the pointer to store the detected formats
     816                 :            :  * @bpsp: the pointer to store the detected format widths
     817                 :            :  *
     818                 :            :  * Queries the supported PCM rates and formats.  The NULL @ratesp, @formatsp
     819                 :            :  * or @bsps argument is ignored.
     820                 :            :  *
     821                 :            :  * Returns 0 if successful, otherwise a negative error code.
     822                 :            :  */
     823                 :          0 : int snd_hdac_query_supported_pcm(struct hdac_device *codec, hda_nid_t nid,
     824                 :            :                                  u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
     825                 :            : {
     826                 :          0 :         unsigned int i, val, wcaps;
     827                 :            : 
     828                 :          0 :         wcaps = get_wcaps(codec, nid);
     829                 :          0 :         val = query_pcm_param(codec, nid);
     830                 :            : 
     831         [ #  # ]:          0 :         if (ratesp) {
     832                 :            :                 u32 rates = 0;
     833         [ #  # ]:          0 :                 for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) {
     834         [ #  # ]:          0 :                         if (val & (1 << i))
     835                 :          0 :                                 rates |= rate_bits[i].alsa_bits;
     836                 :            :                 }
     837         [ #  # ]:          0 :                 if (rates == 0) {
     838                 :          0 :                         dev_err(&codec->dev,
     839                 :            :                                 "rates == 0 (nid=0x%x, val=0x%x, ovrd=%i)\n",
     840                 :            :                                 nid, val,
     841                 :            :                                 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0);
     842                 :          0 :                         return -EIO;
     843                 :            :                 }
     844                 :          0 :                 *ratesp = rates;
     845                 :            :         }
     846                 :            : 
     847         [ #  # ]:          0 :         if (formatsp || bpsp) {
     848                 :          0 :                 u64 formats = 0;
     849                 :          0 :                 unsigned int streams, bps;
     850                 :            : 
     851                 :          0 :                 streams = query_stream_param(codec, nid);
     852         [ #  # ]:          0 :                 if (!streams)
     853                 :            :                         return -EIO;
     854                 :            : 
     855                 :          0 :                 bps = 0;
     856         [ #  # ]:          0 :                 if (streams & AC_SUPFMT_PCM) {
     857         [ #  # ]:          0 :                         if (val & AC_SUPPCM_BITS_8) {
     858                 :          0 :                                 formats |= SNDRV_PCM_FMTBIT_U8;
     859                 :          0 :                                 bps = 8;
     860                 :            :                         }
     861         [ #  # ]:          0 :                         if (val & AC_SUPPCM_BITS_16) {
     862                 :          0 :                                 formats |= SNDRV_PCM_FMTBIT_S16_LE;
     863                 :          0 :                                 bps = 16;
     864                 :            :                         }
     865         [ #  # ]:          0 :                         if (wcaps & AC_WCAP_DIGITAL) {
     866         [ #  # ]:          0 :                                 if (val & AC_SUPPCM_BITS_32)
     867                 :          0 :                                         formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
     868         [ #  # ]:          0 :                                 if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))
     869                 :          0 :                                         formats |= SNDRV_PCM_FMTBIT_S32_LE;
     870         [ #  # ]:          0 :                                 if (val & AC_SUPPCM_BITS_24)
     871                 :            :                                         bps = 24;
     872         [ #  # ]:          0 :                                 else if (val & AC_SUPPCM_BITS_20)
     873                 :          0 :                                         bps = 20;
     874         [ #  # ]:          0 :                         } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
     875                 :            :                                           AC_SUPPCM_BITS_32)) {
     876                 :          0 :                                 formats |= SNDRV_PCM_FMTBIT_S32_LE;
     877         [ #  # ]:          0 :                                 if (val & AC_SUPPCM_BITS_32)
     878                 :            :                                         bps = 32;
     879         [ #  # ]:          0 :                                 else if (val & AC_SUPPCM_BITS_24)
     880                 :            :                                         bps = 24;
     881         [ #  # ]:          0 :                                 else if (val & AC_SUPPCM_BITS_20)
     882                 :          0 :                                         bps = 20;
     883                 :            :                         }
     884                 :            :                 }
     885                 :            : #if 0 /* FIXME: CS4206 doesn't work, which is the only codec supporting float */
     886                 :            :                 if (streams & AC_SUPFMT_FLOAT32) {
     887                 :            :                         formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
     888                 :            :                         if (!bps)
     889                 :            :                                 bps = 32;
     890                 :            :                 }
     891                 :            : #endif
     892         [ #  # ]:          0 :                 if (streams == AC_SUPFMT_AC3) {
     893                 :            :                         /* should be exclusive */
     894                 :            :                         /* temporary hack: we have still no proper support
     895                 :            :                          * for the direct AC3 stream...
     896                 :            :                          */
     897                 :          0 :                         formats |= SNDRV_PCM_FMTBIT_U8;
     898                 :          0 :                         bps = 8;
     899                 :            :                 }
     900         [ #  # ]:          0 :                 if (formats == 0) {
     901                 :          0 :                         dev_err(&codec->dev,
     902                 :            :                                 "formats == 0 (nid=0x%x, val=0x%x, ovrd=%i, streams=0x%x)\n",
     903                 :            :                                 nid, val,
     904                 :            :                                 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0,
     905                 :            :                                 streams);
     906                 :          0 :                         return -EIO;
     907                 :            :                 }
     908         [ #  # ]:          0 :                 if (formatsp)
     909                 :          0 :                         *formatsp = formats;
     910         [ #  # ]:          0 :                 if (bpsp)
     911                 :          0 :                         *bpsp = bps;
     912                 :            :         }
     913                 :            : 
     914                 :            :         return 0;
     915                 :            : }
     916                 :            : EXPORT_SYMBOL_GPL(snd_hdac_query_supported_pcm);
     917                 :            : 
     918                 :            : /**
     919                 :            :  * snd_hdac_is_supported_format - Check the validity of the format
     920                 :            :  * @codec: the codec object
     921                 :            :  * @nid: NID to check
     922                 :            :  * @format: the HD-audio format value to check
     923                 :            :  *
     924                 :            :  * Check whether the given node supports the format value.
     925                 :            :  *
     926                 :            :  * Returns true if supported, false if not.
     927                 :            :  */
     928                 :          0 : bool snd_hdac_is_supported_format(struct hdac_device *codec, hda_nid_t nid,
     929                 :            :                                   unsigned int format)
     930                 :            : {
     931                 :          0 :         int i;
     932                 :          0 :         unsigned int val = 0, rate, stream;
     933                 :            : 
     934                 :          0 :         val = query_pcm_param(codec, nid);
     935         [ #  # ]:          0 :         if (!val)
     936                 :            :                 return false;
     937                 :            : 
     938                 :          0 :         rate = format & 0xff00;
     939         [ #  # ]:          0 :         for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
     940         [ #  # ]:          0 :                 if (rate_bits[i].hda_fmt == rate) {
     941         [ #  # ]:          0 :                         if (val & (1 << i))
     942                 :            :                                 break;
     943                 :            :                         return false;
     944                 :            :                 }
     945         [ #  # ]:          0 :         if (i >= AC_PAR_PCM_RATE_BITS)
     946                 :            :                 return false;
     947                 :            : 
     948                 :          0 :         stream = query_stream_param(codec, nid);
     949         [ #  # ]:          0 :         if (!stream)
     950                 :            :                 return false;
     951                 :            : 
     952         [ #  # ]:          0 :         if (stream & AC_SUPFMT_PCM) {
     953   [ #  #  #  #  :          0 :                 switch (format & 0xf0) {
                   #  # ]
     954                 :          0 :                 case 0x00:
     955         [ #  # ]:          0 :                         if (!(val & AC_SUPPCM_BITS_8))
     956                 :          0 :                                 return false;
     957                 :            :                         break;
     958                 :          0 :                 case 0x10:
     959         [ #  # ]:          0 :                         if (!(val & AC_SUPPCM_BITS_16))
     960                 :          0 :                                 return false;
     961                 :            :                         break;
     962                 :          0 :                 case 0x20:
     963         [ #  # ]:          0 :                         if (!(val & AC_SUPPCM_BITS_20))
     964                 :          0 :                                 return false;
     965                 :            :                         break;
     966                 :          0 :                 case 0x30:
     967         [ #  # ]:          0 :                         if (!(val & AC_SUPPCM_BITS_24))
     968                 :          0 :                                 return false;
     969                 :            :                         break;
     970                 :          0 :                 case 0x40:
     971         [ #  # ]:          0 :                         if (!(val & AC_SUPPCM_BITS_32))
     972                 :          0 :                                 return false;
     973                 :            :                         break;
     974                 :            :                 default:
     975                 :            :                         return false;
     976                 :            :                 }
     977                 :            :         } else {
     978                 :            :                 /* FIXME: check for float32 and AC3? */
     979                 :            :         }
     980                 :            : 
     981                 :            :         return true;
     982                 :            : }
     983                 :            : EXPORT_SYMBOL_GPL(snd_hdac_is_supported_format);
     984                 :            : 
     985                 :          0 : static unsigned int codec_read(struct hdac_device *hdac, hda_nid_t nid,
     986                 :            :                         int flags, unsigned int verb, unsigned int parm)
     987                 :            : {
     988                 :          0 :         unsigned int cmd = snd_hdac_make_cmd(hdac, nid, verb, parm);
     989                 :          0 :         unsigned int res;
     990                 :            : 
     991         [ #  # ]:          0 :         if (snd_hdac_exec_verb(hdac, cmd, flags, &res))
     992                 :            :                 return -1;
     993                 :            : 
     994                 :          0 :         return res;
     995                 :            : }
     996                 :            : 
     997                 :          0 : static int codec_write(struct hdac_device *hdac, hda_nid_t nid,
     998                 :            :                         int flags, unsigned int verb, unsigned int parm)
     999                 :            : {
    1000                 :          0 :         unsigned int cmd = snd_hdac_make_cmd(hdac, nid, verb, parm);
    1001                 :            : 
    1002                 :          0 :         return snd_hdac_exec_verb(hdac, cmd, flags, NULL);
    1003                 :            : }
    1004                 :            : 
    1005                 :            : /**
    1006                 :            :  * snd_hdac_codec_read - send a command and get the response
    1007                 :            :  * @hdac: the HDAC device
    1008                 :            :  * @nid: NID to send the command
    1009                 :            :  * @flags: optional bit flags
    1010                 :            :  * @verb: the verb to send
    1011                 :            :  * @parm: the parameter for the verb
    1012                 :            :  *
    1013                 :            :  * Send a single command and read the corresponding response.
    1014                 :            :  *
    1015                 :            :  * Returns the obtained response value, or -1 for an error.
    1016                 :            :  */
    1017                 :          0 : int snd_hdac_codec_read(struct hdac_device *hdac, hda_nid_t nid,
    1018                 :            :                         int flags, unsigned int verb, unsigned int parm)
    1019                 :            : {
    1020                 :          0 :         return codec_read(hdac, nid, flags, verb, parm);
    1021                 :            : }
    1022                 :            : EXPORT_SYMBOL_GPL(snd_hdac_codec_read);
    1023                 :            : 
    1024                 :            : /**
    1025                 :            :  * snd_hdac_codec_write - send a single command without waiting for response
    1026                 :            :  * @hdac: the HDAC device
    1027                 :            :  * @nid: NID to send the command
    1028                 :            :  * @flags: optional bit flags
    1029                 :            :  * @verb: the verb to send
    1030                 :            :  * @parm: the parameter for the verb
    1031                 :            :  *
    1032                 :            :  * Send a single command without waiting for response.
    1033                 :            :  *
    1034                 :            :  * Returns 0 if successful, or a negative error code.
    1035                 :            :  */
    1036                 :          0 : int snd_hdac_codec_write(struct hdac_device *hdac, hda_nid_t nid,
    1037                 :            :                         int flags, unsigned int verb, unsigned int parm)
    1038                 :            : {
    1039                 :          0 :         return codec_write(hdac, nid, flags, verb, parm);
    1040                 :            : }
    1041                 :            : EXPORT_SYMBOL_GPL(snd_hdac_codec_write);
    1042                 :            : 
    1043                 :            : /**
    1044                 :            :  * snd_hdac_check_power_state - check whether the actual power state matches
    1045                 :            :  * with the target state
    1046                 :            :  *
    1047                 :            :  * @hdac: the HDAC device
    1048                 :            :  * @nid: NID to send the command
    1049                 :            :  * @target_state: target state to check for
    1050                 :            :  *
    1051                 :            :  * Return true if state matches, false if not
    1052                 :            :  */
    1053                 :          0 : bool snd_hdac_check_power_state(struct hdac_device *hdac,
    1054                 :            :                 hda_nid_t nid, unsigned int target_state)
    1055                 :            : {
    1056                 :          0 :         unsigned int state = codec_read(hdac, nid, 0,
    1057                 :            :                                 AC_VERB_GET_POWER_STATE, 0);
    1058                 :            : 
    1059         [ #  # ]:          0 :         if (state & AC_PWRST_ERROR)
    1060                 :            :                 return true;
    1061                 :          0 :         state = (state >> 4) & 0x0f;
    1062                 :          0 :         return (state == target_state);
    1063                 :            : }
    1064                 :            : EXPORT_SYMBOL_GPL(snd_hdac_check_power_state);
    1065                 :            : /**
    1066                 :            :  * snd_hdac_sync_power_state - wait until actual power state matches
    1067                 :            :  * with the target state
    1068                 :            :  *
    1069                 :            :  * @codec: the HDAC device
    1070                 :            :  * @nid: NID to send the command
    1071                 :            :  * @power_state: target power state to wait for
    1072                 :            :  *
    1073                 :            :  * Return power state or PS_ERROR if codec rejects GET verb.
    1074                 :            :  */
    1075                 :          0 : unsigned int snd_hdac_sync_power_state(struct hdac_device *codec,
    1076                 :            :                         hda_nid_t nid, unsigned int power_state)
    1077                 :            : {
    1078                 :          0 :         unsigned long end_time = jiffies + msecs_to_jiffies(500);
    1079                 :          0 :         unsigned int state, actual_state, count;
    1080                 :            : 
    1081         [ #  # ]:          0 :         for (count = 0; count < 500; count++) {
    1082                 :          0 :                 state = snd_hdac_codec_read(codec, nid, 0,
    1083                 :            :                                 AC_VERB_GET_POWER_STATE, 0);
    1084         [ #  # ]:          0 :                 if (state & AC_PWRST_ERROR) {
    1085                 :          0 :                         msleep(20);
    1086                 :          0 :                         break;
    1087                 :            :                 }
    1088                 :          0 :                 actual_state = (state >> 4) & 0x0f;
    1089         [ #  # ]:          0 :                 if (actual_state == power_state)
    1090                 :            :                         break;
    1091         [ #  # ]:          0 :                 if (time_after_eq(jiffies, end_time))
    1092                 :            :                         break;
    1093                 :            :                 /* wait until the codec reachs to the target state */
    1094                 :          0 :                 msleep(1);
    1095                 :            :         }
    1096                 :          0 :         return state;
    1097                 :            : }
    1098                 :            : EXPORT_SYMBOL_GPL(snd_hdac_sync_power_state);

Generated by: LCOV version 1.14