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