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 err = snd_hdac_exec_verb(codec, reg, 0, val); 250 if (err < 0) 251 return err; 252 /* special handling for asymmetric reads */ 253 if (verb == AC_VERB_GET_POWER_STATE) { 254 if (*val & AC_PWRST_ERROR) 255 *val = -1; 256 else /* take only the actual state */ 257 *val = (*val >> 4) & 0x0f; 258 } 259 return 0; 260 } 261 262 static int hda_reg_write(void *context, unsigned int reg, unsigned int val) 263 { 264 struct hdac_device *codec = context; 265 unsigned int verb; 266 int i, bytes, err; 267 268 reg &= ~0x00080000U; /* drop GET bit */ 269 reg |= (codec->addr << 28); 270 verb = get_verb(reg); 271 272 if (!codec_is_running(codec) && verb != AC_VERB_SET_POWER_STATE) 273 return codec->lazy_cache ? 0 : -EAGAIN; 274 275 if (is_stereo_amp_verb(reg)) 276 return hda_reg_write_stereo_amp(codec, reg, val); 277 278 if (verb == AC_VERB_SET_PROC_COEF) 279 return hda_reg_write_coef(codec, reg, val); 280 281 switch (verb & 0xf00) { 282 case AC_VERB_SET_AMP_GAIN_MUTE: 283 verb = AC_VERB_SET_AMP_GAIN_MUTE; 284 if (reg & AC_AMP_GET_LEFT) 285 verb |= AC_AMP_SET_LEFT >> 8; 286 else 287 verb |= AC_AMP_SET_RIGHT >> 8; 288 if (reg & AC_AMP_GET_OUTPUT) { 289 verb |= AC_AMP_SET_OUTPUT >> 8; 290 } else { 291 verb |= AC_AMP_SET_INPUT >> 8; 292 verb |= reg & 0xf; 293 } 294 break; 295 } 296 297 switch (verb) { 298 case AC_VERB_SET_DIGI_CONVERT_1: 299 bytes = 2; 300 break; 301 case AC_VERB_SET_CONFIG_DEFAULT_BYTES_0: 302 bytes = 4; 303 break; 304 default: 305 bytes = 1; 306 break; 307 } 308 309 for (i = 0; i < bytes; i++) { 310 reg &= ~0xfffff; 311 reg |= (verb + i) << 8 | ((val >> (8 * i)) & 0xff); 312 err = snd_hdac_exec_verb(codec, reg, 0, NULL); 313 if (err < 0) 314 return err; 315 } 316 317 return 0; 318 } 319 320 static const struct regmap_config hda_regmap_cfg = { 321 .name = "hdaudio", 322 .reg_bits = 32, 323 .val_bits = 32, 324 .max_register = 0xfffffff, 325 .writeable_reg = hda_writeable_reg, 326 .readable_reg = hda_readable_reg, 327 .volatile_reg = hda_volatile_reg, 328 .cache_type = REGCACHE_RBTREE, 329 .reg_read = hda_reg_read, 330 .reg_write = hda_reg_write, 331 .use_single_rw = true, 332 }; 333 334 int snd_hdac_regmap_init(struct hdac_device *codec) 335 { 336 struct regmap *regmap; 337 338 regmap = regmap_init(&codec->dev, NULL, codec, &hda_regmap_cfg); 339 if (IS_ERR(regmap)) 340 return PTR_ERR(regmap); 341 codec->regmap = regmap; 342 snd_array_init(&codec->vendor_verbs, sizeof(unsigned int), 8); 343 return 0; 344 } 345 EXPORT_SYMBOL_GPL(snd_hdac_regmap_init); 346 347 void snd_hdac_regmap_exit(struct hdac_device *codec) 348 { 349 if (codec->regmap) { 350 regmap_exit(codec->regmap); 351 codec->regmap = NULL; 352 snd_array_free(&codec->vendor_verbs); 353 } 354 } 355 EXPORT_SYMBOL_GPL(snd_hdac_regmap_exit); 356 357 /** 358 * snd_hdac_regmap_add_vendor_verb - add a vendor-specific verb to regmap 359 * @codec: the codec object 360 * @verb: verb to allow accessing via regmap 361 * 362 * Returns zero for success or a negative error code. 363 */ 364 int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec, 365 unsigned int verb) 366 { 367 unsigned int *p = snd_array_new(&codec->vendor_verbs); 368 369 if (!p) 370 return -ENOMEM; 371 *p = verb | 0x800; /* set GET bit */ 372 return 0; 373 } 374 EXPORT_SYMBOL_GPL(snd_hdac_regmap_add_vendor_verb); 375 376 /* 377 * helper functions 378 */ 379 380 /* write a pseudo-register value (w/o power sequence) */ 381 static int reg_raw_write(struct hdac_device *codec, unsigned int reg, 382 unsigned int val) 383 { 384 if (!codec->regmap) 385 return hda_reg_write(codec, reg, val); 386 else 387 return regmap_write(codec->regmap, reg, val); 388 } 389 390 /** 391 * snd_hdac_regmap_write_raw - write a pseudo register with power mgmt 392 * @codec: the codec object 393 * @reg: pseudo register 394 * @val: value to write 395 * 396 * Returns zero if successful or a negative error code. 397 */ 398 int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg, 399 unsigned int val) 400 { 401 int err; 402 403 err = reg_raw_write(codec, reg, val); 404 if (err == -EAGAIN) { 405 snd_hdac_power_up_pm(codec); 406 err = reg_raw_write(codec, reg, val); 407 snd_hdac_power_down_pm(codec); 408 } 409 return err; 410 } 411 EXPORT_SYMBOL_GPL(snd_hdac_regmap_write_raw); 412 413 static int reg_raw_read(struct hdac_device *codec, unsigned int reg, 414 unsigned int *val) 415 { 416 if (!codec->regmap) 417 return hda_reg_read(codec, reg, val); 418 else 419 return regmap_read(codec->regmap, reg, val); 420 } 421 422 /** 423 * snd_hdac_regmap_read_raw - read a pseudo register with power mgmt 424 * @codec: the codec object 425 * @reg: pseudo register 426 * @val: pointer to store the read value 427 * 428 * Returns zero if successful or a negative error code. 429 */ 430 int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg, 431 unsigned int *val) 432 { 433 int err; 434 435 err = reg_raw_read(codec, reg, val); 436 if (err == -EAGAIN) { 437 snd_hdac_power_up_pm(codec); 438 err = reg_raw_read(codec, reg, val); 439 snd_hdac_power_down_pm(codec); 440 } 441 return err; 442 } 443 EXPORT_SYMBOL_GPL(snd_hdac_regmap_read_raw); 444 445 /** 446 * snd_hdac_regmap_update_raw - update a pseudo register with power mgmt 447 * @codec: the codec object 448 * @reg: pseudo register 449 * @mask: bit mask to udpate 450 * @val: value to update 451 * 452 * Returns zero if successful or a negative error code. 453 */ 454 int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg, 455 unsigned int mask, unsigned int val) 456 { 457 unsigned int orig; 458 int err; 459 460 val &= mask; 461 err = snd_hdac_regmap_read_raw(codec, reg, &orig); 462 if (err < 0) 463 return err; 464 val |= orig & ~mask; 465 if (val == orig) 466 return 0; 467 err = snd_hdac_regmap_write_raw(codec, reg, val); 468 if (err < 0) 469 return err; 470 return 1; 471 } 472 EXPORT_SYMBOL_GPL(snd_hdac_regmap_update_raw); 473