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