linux/sound/hda/hdac_regmap.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Regmap support for HD-audio verbs
   4 *
   5 * A virtual register is translated to one or more hda verbs for write,
   6 * vice versa for read.
   7 *
   8 * A few limitations:
   9 * - Provided for not all verbs but only subset standard non-volatile verbs.
  10 * - For reading, only AC_VERB_GET_* variants can be used.
  11 * - For writing, mapped to the *corresponding* AC_VERB_SET_* variants,
  12 *   so can't handle asymmetric verbs for read and write
  13 */
  14
  15#include <linux/slab.h>
  16#include <linux/device.h>
  17#include <linux/regmap.h>
  18#include <linux/export.h>
  19#include <linux/pm.h>
  20#include <linux/pm_runtime.h>
  21#include <sound/core.h>
  22#include <sound/hdaudio.h>
  23#include <sound/hda_regmap.h>
  24#include "local.h"
  25
  26static int codec_pm_lock(struct hdac_device *codec)
  27{
  28        return snd_hdac_keep_power_up(codec);
  29}
  30
  31static void codec_pm_unlock(struct hdac_device *codec, int lock)
  32{
  33        if (lock == 1)
  34                snd_hdac_power_down_pm(codec);
  35}
  36
  37#define get_verb(reg)   (((reg) >> 8) & 0xfff)
  38
  39static bool hda_volatile_reg(struct device *dev, unsigned int reg)
  40{
  41        struct hdac_device *codec = dev_to_hdac_dev(dev);
  42        unsigned int verb = get_verb(reg);
  43
  44        switch (verb) {
  45        case AC_VERB_GET_PROC_COEF:
  46                return !codec->cache_coef;
  47        case AC_VERB_GET_COEF_INDEX:
  48        case AC_VERB_GET_PROC_STATE:
  49        case AC_VERB_GET_POWER_STATE:
  50        case AC_VERB_GET_PIN_SENSE:
  51        case AC_VERB_GET_HDMI_DIP_SIZE:
  52        case AC_VERB_GET_HDMI_ELDD:
  53        case AC_VERB_GET_HDMI_DIP_INDEX:
  54        case AC_VERB_GET_HDMI_DIP_DATA:
  55        case AC_VERB_GET_HDMI_DIP_XMIT:
  56        case AC_VERB_GET_HDMI_CP_CTRL:
  57        case AC_VERB_GET_HDMI_CHAN_SLOT:
  58        case AC_VERB_GET_DEVICE_SEL:
  59        case AC_VERB_GET_DEVICE_LIST:   /* read-only volatile */
  60                return true;
  61        }
  62
  63        return false;
  64}
  65
  66static bool hda_writeable_reg(struct device *dev, unsigned int reg)
  67{
  68        struct hdac_device *codec = dev_to_hdac_dev(dev);
  69        unsigned int verb = get_verb(reg);
  70        const unsigned int *v;
  71        int i;
  72
  73        snd_array_for_each(&codec->vendor_verbs, i, v) {
  74                if (verb == *v)
  75                        return true;
  76        }
  77
  78        if (codec->caps_overwriting)
  79                return true;
  80
  81        switch (verb & 0xf00) {
  82        case AC_VERB_GET_STREAM_FORMAT:
  83        case AC_VERB_GET_AMP_GAIN_MUTE:
  84                return true;
  85        case AC_VERB_GET_PROC_COEF:
  86                return codec->cache_coef;
  87        case 0xf00:
  88                break;
  89        default:
  90                return false;
  91        }
  92
  93        switch (verb) {
  94        case AC_VERB_GET_CONNECT_SEL:
  95        case AC_VERB_GET_SDI_SELECT:
  96        case AC_VERB_GET_PIN_WIDGET_CONTROL:
  97        case AC_VERB_GET_UNSOLICITED_RESPONSE: /* only as SET_UNSOLICITED_ENABLE */
  98        case AC_VERB_GET_BEEP_CONTROL:
  99        case AC_VERB_GET_EAPD_BTLENABLE:
 100        case AC_VERB_GET_DIGI_CONVERT_1:
 101        case AC_VERB_GET_DIGI_CONVERT_2: /* only for beep control */
 102        case AC_VERB_GET_VOLUME_KNOB_CONTROL:
 103        case AC_VERB_GET_GPIO_MASK:
 104        case AC_VERB_GET_GPIO_DIRECTION:
 105        case AC_VERB_GET_GPIO_DATA: /* not for volatile read */
 106        case AC_VERB_GET_GPIO_WAKE_MASK:
 107        case AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK:
 108        case AC_VERB_GET_GPIO_STICKY_MASK:
 109                return true;
 110        }
 111
 112        return false;
 113}
 114
 115static bool hda_readable_reg(struct device *dev, unsigned int reg)
 116{
 117        struct hdac_device *codec = dev_to_hdac_dev(dev);
 118        unsigned int verb = get_verb(reg);
 119
 120        if (codec->caps_overwriting)
 121                return true;
 122
 123        switch (verb) {
 124        case AC_VERB_PARAMETERS:
 125        case AC_VERB_GET_CONNECT_LIST:
 126        case AC_VERB_GET_SUBSYSTEM_ID:
 127                return true;
 128        /* below are basically writable, but disabled for reducing unnecessary
 129         * writes at sync
 130         */
 131        case AC_VERB_GET_CONFIG_DEFAULT: /* usually just read */
 132        case AC_VERB_GET_CONV: /* managed in PCM code */
 133        case AC_VERB_GET_CVT_CHAN_COUNT: /* managed in HDMI CA code */
 134                return true;
 135        }
 136
 137        return hda_writeable_reg(dev, reg);
 138}
 139
 140/*
 141 * Stereo amp pseudo register:
 142 * for making easier to handle the stereo volume control, we provide a
 143 * fake register to deal both left and right channels by a single
 144 * (pseudo) register access.  A verb consisting of SET_AMP_GAIN with
 145 * *both* SET_LEFT and SET_RIGHT bits takes a 16bit value, the lower 8bit
 146 * for the left and the upper 8bit for the right channel.
 147 */
 148static bool is_stereo_amp_verb(unsigned int reg)
 149{
 150        if (((reg >> 8) & 0x700) != AC_VERB_SET_AMP_GAIN_MUTE)
 151                return false;
 152        return (reg & (AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT)) ==
 153                (AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT);
 154}
 155
 156/* read a pseudo stereo amp register (16bit left+right) */
 157static int hda_reg_read_stereo_amp(struct hdac_device *codec,
 158                                   unsigned int reg, unsigned int *val)
 159{
 160        unsigned int left, right;
 161        int err;
 162
 163        reg &= ~(AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT);
 164        err = snd_hdac_exec_verb(codec, reg | AC_AMP_GET_LEFT, 0, &left);
 165        if (err < 0)
 166                return err;
 167        err = snd_hdac_exec_verb(codec, reg | AC_AMP_GET_RIGHT, 0, &right);
 168        if (err < 0)
 169                return err;
 170        *val = left | (right << 8);
 171        return 0;
 172}
 173
 174/* write a pseudo stereo amp register (16bit left+right) */
 175static int hda_reg_write_stereo_amp(struct hdac_device *codec,
 176                                    unsigned int reg, unsigned int val)
 177{
 178        int err;
 179        unsigned int verb, left, right;
 180
 181        verb = AC_VERB_SET_AMP_GAIN_MUTE << 8;
 182        if (reg & AC_AMP_GET_OUTPUT)
 183                verb |= AC_AMP_SET_OUTPUT;
 184        else
 185                verb |= AC_AMP_SET_INPUT | ((reg & 0xf) << 8);
 186        reg = (reg & ~0xfffff) | verb;
 187
 188        left = val & 0xff;
 189        right = (val >> 8) & 0xff;
 190        if (left == right) {
 191                reg |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
 192                return snd_hdac_exec_verb(codec, reg | left, 0, NULL);
 193        }
 194
 195        err = snd_hdac_exec_verb(codec, reg | AC_AMP_SET_LEFT | left, 0, NULL);
 196        if (err < 0)
 197                return err;
 198        err = snd_hdac_exec_verb(codec, reg | AC_AMP_SET_RIGHT | right, 0, NULL);
 199        if (err < 0)
 200                return err;
 201        return 0;
 202}
 203
 204/* read a pseudo coef register (16bit) */
 205static int hda_reg_read_coef(struct hdac_device *codec, unsigned int reg,
 206                             unsigned int *val)
 207{
 208        unsigned int verb;
 209        int err;
 210
 211        if (!codec->cache_coef)
 212                return -EINVAL;
 213        /* LSB 8bit = coef index */
 214        verb = (reg & ~0xfff00) | (AC_VERB_SET_COEF_INDEX << 8);
 215        err = snd_hdac_exec_verb(codec, verb, 0, NULL);
 216        if (err < 0)
 217                return err;
 218        verb = (reg & ~0xfffff) | (AC_VERB_GET_COEF_INDEX << 8);
 219        return snd_hdac_exec_verb(codec, verb, 0, val);
 220}
 221
 222/* write a pseudo coef register (16bit) */
 223static int hda_reg_write_coef(struct hdac_device *codec, unsigned int reg,
 224                              unsigned int val)
 225{
 226        unsigned int verb;
 227        int err;
 228
 229        if (!codec->cache_coef)
 230                return -EINVAL;
 231        /* LSB 8bit = coef index */
 232        verb = (reg & ~0xfff00) | (AC_VERB_SET_COEF_INDEX << 8);
 233        err = snd_hdac_exec_verb(codec, verb, 0, NULL);
 234        if (err < 0)
 235                return err;
 236        verb = (reg & ~0xfffff) | (AC_VERB_GET_COEF_INDEX << 8) |
 237                (val & 0xffff);
 238        return snd_hdac_exec_verb(codec, verb, 0, NULL);
 239}
 240
 241static int hda_reg_read(void *context, unsigned int reg, unsigned int *val)
 242{
 243        struct hdac_device *codec = context;
 244        int verb = get_verb(reg);
 245        int err;
 246        int pm_lock = 0;
 247
 248        if (verb != AC_VERB_GET_POWER_STATE) {
 249                pm_lock = codec_pm_lock(codec);
 250                if (pm_lock < 0)
 251                        return -EAGAIN;
 252        }
 253        reg |= (codec->addr << 28);
 254        if (is_stereo_amp_verb(reg)) {
 255                err = hda_reg_read_stereo_amp(codec, reg, val);
 256                goto out;
 257        }
 258        if (verb == AC_VERB_GET_PROC_COEF) {
 259                err = hda_reg_read_coef(codec, reg, val);
 260                goto out;
 261        }
 262        if ((verb & 0x700) == AC_VERB_SET_AMP_GAIN_MUTE)
 263                reg &= ~AC_AMP_FAKE_MUTE;
 264
 265        err = snd_hdac_exec_verb(codec, reg, 0, val);
 266        if (err < 0)
 267                goto out;
 268        /* special handling for asymmetric reads */
 269        if (verb == AC_VERB_GET_POWER_STATE) {
 270                if (*val & AC_PWRST_ERROR)
 271                        *val = -1;
 272                else /* take only the actual state */
 273                        *val = (*val >> 4) & 0x0f;
 274        }
 275 out:
 276        codec_pm_unlock(codec, pm_lock);
 277        return err;
 278}
 279
 280static int hda_reg_write(void *context, unsigned int reg, unsigned int val)
 281{
 282        struct hdac_device *codec = context;
 283        unsigned int verb;
 284        int i, bytes, err;
 285        int pm_lock = 0;
 286
 287        if (codec->caps_overwriting)
 288                return 0;
 289
 290        reg &= ~0x00080000U; /* drop GET bit */
 291        reg |= (codec->addr << 28);
 292        verb = get_verb(reg);
 293
 294        if (verb != AC_VERB_SET_POWER_STATE) {
 295                pm_lock = codec_pm_lock(codec);
 296                if (pm_lock < 0)
 297                        return codec->lazy_cache ? 0 : -EAGAIN;
 298        }
 299
 300        if (is_stereo_amp_verb(reg)) {
 301                err = hda_reg_write_stereo_amp(codec, reg, val);
 302                goto out;
 303        }
 304
 305        if (verb == AC_VERB_SET_PROC_COEF) {
 306                err = hda_reg_write_coef(codec, reg, val);
 307                goto out;
 308        }
 309
 310        switch (verb & 0xf00) {
 311        case AC_VERB_SET_AMP_GAIN_MUTE:
 312                if ((reg & AC_AMP_FAKE_MUTE) && (val & AC_AMP_MUTE))
 313                        val = 0;
 314                verb = AC_VERB_SET_AMP_GAIN_MUTE;
 315                if (reg & AC_AMP_GET_LEFT)
 316                        verb |= AC_AMP_SET_LEFT >> 8;
 317                else
 318                        verb |= AC_AMP_SET_RIGHT >> 8;
 319                if (reg & AC_AMP_GET_OUTPUT) {
 320                        verb |= AC_AMP_SET_OUTPUT >> 8;
 321                } else {
 322                        verb |= AC_AMP_SET_INPUT >> 8;
 323                        verb |= reg & 0xf;
 324                }
 325                break;
 326        }
 327
 328        switch (verb) {
 329        case AC_VERB_SET_DIGI_CONVERT_1:
 330                bytes = 2;
 331                break;
 332        case AC_VERB_SET_CONFIG_DEFAULT_BYTES_0:
 333                bytes = 4;
 334                break;
 335        default:
 336                bytes = 1;
 337                break;
 338        }
 339
 340        for (i = 0; i < bytes; i++) {
 341                reg &= ~0xfffff;
 342                reg |= (verb + i) << 8 | ((val >> (8 * i)) & 0xff);
 343                err = snd_hdac_exec_verb(codec, reg, 0, NULL);
 344                if (err < 0)
 345                        goto out;
 346        }
 347
 348 out:
 349        codec_pm_unlock(codec, pm_lock);
 350        return err;
 351}
 352
 353static const struct regmap_config hda_regmap_cfg = {
 354        .name = "hdaudio",
 355        .reg_bits = 32,
 356        .val_bits = 32,
 357        .max_register = 0xfffffff,
 358        .writeable_reg = hda_writeable_reg,
 359        .readable_reg = hda_readable_reg,
 360        .volatile_reg = hda_volatile_reg,
 361        .cache_type = REGCACHE_RBTREE,
 362        .reg_read = hda_reg_read,
 363        .reg_write = hda_reg_write,
 364        .use_single_read = true,
 365        .use_single_write = true,
 366        .disable_locking = true,
 367};
 368
 369/**
 370 * snd_hdac_regmap_init - Initialize regmap for HDA register accesses
 371 * @codec: the codec object
 372 *
 373 * Returns zero for success or a negative error code.
 374 */
 375int snd_hdac_regmap_init(struct hdac_device *codec)
 376{
 377        struct regmap *regmap;
 378
 379        regmap = regmap_init(&codec->dev, NULL, codec, &hda_regmap_cfg);
 380        if (IS_ERR(regmap))
 381                return PTR_ERR(regmap);
 382        codec->regmap = regmap;
 383        snd_array_init(&codec->vendor_verbs, sizeof(unsigned int), 8);
 384        return 0;
 385}
 386EXPORT_SYMBOL_GPL(snd_hdac_regmap_init);
 387
 388/**
 389 * snd_hdac_regmap_exit - Release the regmap from HDA codec
 390 * @codec: the codec object
 391 */
 392void snd_hdac_regmap_exit(struct hdac_device *codec)
 393{
 394        if (codec->regmap) {
 395                regmap_exit(codec->regmap);
 396                codec->regmap = NULL;
 397                snd_array_free(&codec->vendor_verbs);
 398        }
 399}
 400EXPORT_SYMBOL_GPL(snd_hdac_regmap_exit);
 401
 402/**
 403 * snd_hdac_regmap_add_vendor_verb - add a vendor-specific verb to regmap
 404 * @codec: the codec object
 405 * @verb: verb to allow accessing via regmap
 406 *
 407 * Returns zero for success or a negative error code.
 408 */
 409int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
 410                                    unsigned int verb)
 411{
 412        unsigned int *p = snd_array_new(&codec->vendor_verbs);
 413
 414        if (!p)
 415                return -ENOMEM;
 416        *p = verb | 0x800; /* set GET bit */
 417        return 0;
 418}
 419EXPORT_SYMBOL_GPL(snd_hdac_regmap_add_vendor_verb);
 420
 421/*
 422 * helper functions
 423 */
 424
 425/* write a pseudo-register value (w/o power sequence) */
 426static int reg_raw_write(struct hdac_device *codec, unsigned int reg,
 427                         unsigned int val)
 428{
 429        int err;
 430
 431        mutex_lock(&codec->regmap_lock);
 432        if (!codec->regmap)
 433                err = hda_reg_write(codec, reg, val);
 434        else
 435                err = regmap_write(codec->regmap, reg, val);
 436        mutex_unlock(&codec->regmap_lock);
 437        return err;
 438}
 439
 440/* a helper macro to call @func_call; retry with power-up if failed */
 441#define CALL_RAW_FUNC(codec, func_call)                         \
 442        ({                                                      \
 443                int _err = func_call;                           \
 444                if (_err == -EAGAIN) {                          \
 445                        _err = snd_hdac_power_up_pm(codec);     \
 446                        if (_err >= 0)                          \
 447                                _err = func_call;               \
 448                        snd_hdac_power_down_pm(codec);          \
 449                }                                               \
 450                _err;})
 451
 452/**
 453 * snd_hdac_regmap_write_raw - write a pseudo register with power mgmt
 454 * @codec: the codec object
 455 * @reg: pseudo register
 456 * @val: value to write
 457 *
 458 * Returns zero if successful or a negative error code.
 459 */
 460int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
 461                              unsigned int val)
 462{
 463        return CALL_RAW_FUNC(codec, reg_raw_write(codec, reg, val));
 464}
 465EXPORT_SYMBOL_GPL(snd_hdac_regmap_write_raw);
 466
 467static int reg_raw_read(struct hdac_device *codec, unsigned int reg,
 468                        unsigned int *val, bool uncached)
 469{
 470        int err;
 471
 472        mutex_lock(&codec->regmap_lock);
 473        if (uncached || !codec->regmap)
 474                err = hda_reg_read(codec, reg, val);
 475        else
 476                err = regmap_read(codec->regmap, reg, val);
 477        mutex_unlock(&codec->regmap_lock);
 478        return err;
 479}
 480
 481static int __snd_hdac_regmap_read_raw(struct hdac_device *codec,
 482                                      unsigned int reg, unsigned int *val,
 483                                      bool uncached)
 484{
 485        return CALL_RAW_FUNC(codec, reg_raw_read(codec, reg, val, uncached));
 486}
 487
 488/**
 489 * snd_hdac_regmap_read_raw - read a pseudo register with power mgmt
 490 * @codec: the codec object
 491 * @reg: pseudo register
 492 * @val: pointer to store the read value
 493 *
 494 * Returns zero if successful or a negative error code.
 495 */
 496int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
 497                             unsigned int *val)
 498{
 499        return __snd_hdac_regmap_read_raw(codec, reg, val, false);
 500}
 501EXPORT_SYMBOL_GPL(snd_hdac_regmap_read_raw);
 502
 503/* Works like snd_hdac_regmap_read_raw(), but this doesn't read from the
 504 * cache but always via hda verbs.
 505 */
 506int snd_hdac_regmap_read_raw_uncached(struct hdac_device *codec,
 507                                      unsigned int reg, unsigned int *val)
 508{
 509        return __snd_hdac_regmap_read_raw(codec, reg, val, true);
 510}
 511
 512static int reg_raw_update(struct hdac_device *codec, unsigned int reg,
 513                          unsigned int mask, unsigned int val)
 514{
 515        unsigned int orig;
 516        bool change;
 517        int err;
 518
 519        mutex_lock(&codec->regmap_lock);
 520        if (codec->regmap) {
 521                err = regmap_update_bits_check(codec->regmap, reg, mask, val,
 522                                               &change);
 523                if (!err)
 524                        err = change ? 1 : 0;
 525        } else {
 526                err = hda_reg_read(codec, reg, &orig);
 527                if (!err) {
 528                        val &= mask;
 529                        val |= orig & ~mask;
 530                        if (val != orig) {
 531                                err = hda_reg_write(codec, reg, val);
 532                                if (!err)
 533                                        err = 1;
 534                        }
 535                }
 536        }
 537        mutex_unlock(&codec->regmap_lock);
 538        return err;
 539}
 540
 541/**
 542 * snd_hdac_regmap_update_raw - update a pseudo register with power mgmt
 543 * @codec: the codec object
 544 * @reg: pseudo register
 545 * @mask: bit mask to update
 546 * @val: value to update
 547 *
 548 * Returns zero if successful or a negative error code.
 549 */
 550int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
 551                               unsigned int mask, unsigned int val)
 552{
 553        return CALL_RAW_FUNC(codec, reg_raw_update(codec, reg, mask, val));
 554}
 555EXPORT_SYMBOL_GPL(snd_hdac_regmap_update_raw);
 556
 557static int reg_raw_update_once(struct hdac_device *codec, unsigned int reg,
 558                               unsigned int mask, unsigned int val)
 559{
 560        unsigned int orig;
 561        int err;
 562
 563        if (!codec->regmap)
 564                return reg_raw_update(codec, reg, mask, val);
 565
 566        mutex_lock(&codec->regmap_lock);
 567        regcache_cache_only(codec->regmap, true);
 568        err = regmap_read(codec->regmap, reg, &orig);
 569        regcache_cache_only(codec->regmap, false);
 570        if (err < 0)
 571                err = regmap_update_bits(codec->regmap, reg, mask, val);
 572        mutex_unlock(&codec->regmap_lock);
 573        return err;
 574}
 575
 576/**
 577 * snd_hdac_regmap_update_raw_once - initialize the register value only once
 578 * @codec: the codec object
 579 * @reg: pseudo register
 580 * @mask: bit mask to update
 581 * @val: value to update
 582 *
 583 * Performs the update of the register bits only once when the register
 584 * hasn't been initialized yet.  Used in HD-audio legacy driver.
 585 * Returns zero if successful or a negative error code
 586 */
 587int snd_hdac_regmap_update_raw_once(struct hdac_device *codec, unsigned int reg,
 588                                    unsigned int mask, unsigned int val)
 589{
 590        return CALL_RAW_FUNC(codec, reg_raw_update_once(codec, reg, mask, val));
 591}
 592EXPORT_SYMBOL_GPL(snd_hdac_regmap_update_raw_once);
 593
 594/**
 595 * snd_hdac_regmap_sync - sync out the cached values for PM resume
 596 * @codec: the codec object
 597 */
 598void snd_hdac_regmap_sync(struct hdac_device *codec)
 599{
 600        if (codec->regmap) {
 601                mutex_lock(&codec->regmap_lock);
 602                regcache_sync(codec->regmap);
 603                mutex_unlock(&codec->regmap_lock);
 604        }
 605}
 606EXPORT_SYMBOL_GPL(snd_hdac_regmap_sync);
 607