root/sound/pci/hda/hda_jack.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_jack_detectable
  2. read_pin_sense
  3. snd_hda_jack_tbl_get
  4. snd_hda_jack_tbl_get_from_tag
  5. snd_hda_jack_tbl_new
  6. snd_hda_jack_tbl_clear
  7. jack_detect_update
  8. snd_hda_jack_set_dirty_all
  9. snd_hda_pin_sense
  10. snd_hda_jack_detect_state
  11. snd_hda_jack_detect_enable_callback
  12. snd_hda_jack_detect_enable
  13. snd_hda_jack_set_gating_jack
  14. snd_hda_jack_report_sync
  15. get_input_jack_type
  16. hda_free_jack_priv
  17. snd_hda_jack_add_kctl
  18. add_jack_kctl
  19. snd_hda_jack_add_kctls
  20. call_jack_callback
  21. snd_hda_jack_unsol_event
  22. snd_hda_jack_poll_all

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Jack-detection handling for HD-audio
   4  *
   5  * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
   6  */
   7 
   8 #include <linux/init.h>
   9 #include <linux/slab.h>
  10 #include <linux/export.h>
  11 #include <sound/core.h>
  12 #include <sound/control.h>
  13 #include <sound/jack.h>
  14 #include <sound/hda_codec.h>
  15 #include "hda_local.h"
  16 #include "hda_auto_parser.h"
  17 #include "hda_jack.h"
  18 
  19 /**
  20  * is_jack_detectable - Check whether the given pin is jack-detectable
  21  * @codec: the HDA codec
  22  * @nid: pin NID
  23  *
  24  * Check whether the given pin is capable to report the jack detection.
  25  * The jack detection might not work by various reasons, e.g. the jack
  26  * detection is prohibited in the codec level, the pin config has
  27  * AC_DEFCFG_MISC_NO_PRESENCE bit, no unsol support, etc.
  28  */
  29 bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
  30 {
  31         if (codec->no_jack_detect)
  32                 return false;
  33         if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
  34                 return false;
  35         if (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
  36              AC_DEFCFG_MISC_NO_PRESENCE)
  37                 return false;
  38         if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) &&
  39             !codec->jackpoll_interval)
  40                 return false;
  41         return true;
  42 }
  43 EXPORT_SYMBOL_GPL(is_jack_detectable);
  44 
  45 /* execute pin sense measurement */
  46 static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
  47 {
  48         u32 pincap;
  49         u32 val;
  50 
  51         if (!codec->no_trigger_sense) {
  52                 pincap = snd_hda_query_pin_caps(codec, nid);
  53                 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
  54                         snd_hda_codec_read(codec, nid, 0,
  55                                         AC_VERB_SET_PIN_SENSE, 0);
  56         }
  57         val = snd_hda_codec_read(codec, nid, 0,
  58                                   AC_VERB_GET_PIN_SENSE, 0);
  59         if (codec->inv_jack_detect)
  60                 val ^= AC_PINSENSE_PRESENCE;
  61         return val;
  62 }
  63 
  64 /**
  65  * snd_hda_jack_tbl_get - query the jack-table entry for the given NID
  66  * @codec: the HDA codec
  67  * @nid: pin NID to refer to
  68  */
  69 struct hda_jack_tbl *
  70 snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid)
  71 {
  72         struct hda_jack_tbl *jack = codec->jacktbl.list;
  73         int i;
  74 
  75         if (!nid || !jack)
  76                 return NULL;
  77         for (i = 0; i < codec->jacktbl.used; i++, jack++)
  78                 if (jack->nid == nid)
  79                         return jack;
  80         return NULL;
  81 }
  82 EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get);
  83 
  84 /**
  85  * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag
  86  * @codec: the HDA codec
  87  * @tag: tag value to refer to
  88  */
  89 struct hda_jack_tbl *
  90 snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag)
  91 {
  92         struct hda_jack_tbl *jack = codec->jacktbl.list;
  93         int i;
  94 
  95         if (!tag || !jack)
  96                 return NULL;
  97         for (i = 0; i < codec->jacktbl.used; i++, jack++)
  98                 if (jack->tag == tag)
  99                         return jack;
 100         return NULL;
 101 }
 102 EXPORT_SYMBOL_GPL(snd_hda_jack_tbl_get_from_tag);
 103 
 104 /**
 105  * snd_hda_jack_tbl_new - create a jack-table entry for the given NID
 106  * @codec: the HDA codec
 107  * @nid: pin NID to assign
 108  */
 109 static struct hda_jack_tbl *
 110 snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid)
 111 {
 112         struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
 113         if (jack)
 114                 return jack;
 115         jack = snd_array_new(&codec->jacktbl);
 116         if (!jack)
 117                 return NULL;
 118         jack->nid = nid;
 119         jack->jack_dirty = 1;
 120         jack->tag = codec->jacktbl.used;
 121         return jack;
 122 }
 123 
 124 void snd_hda_jack_tbl_clear(struct hda_codec *codec)
 125 {
 126         struct hda_jack_tbl *jack = codec->jacktbl.list;
 127         int i;
 128 
 129         for (i = 0; i < codec->jacktbl.used; i++, jack++) {
 130                 struct hda_jack_callback *cb, *next;
 131 
 132                 /* free jack instances manually when clearing/reconfiguring */
 133                 if (!codec->bus->shutdown && jack->jack)
 134                         snd_device_free(codec->card, jack->jack);
 135 
 136                 for (cb = jack->callback; cb; cb = next) {
 137                         next = cb->next;
 138                         kfree(cb);
 139                 }
 140         }
 141         snd_array_free(&codec->jacktbl);
 142 }
 143 
 144 #define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE)
 145 
 146 /* update the cached value and notification flag if needed */
 147 static void jack_detect_update(struct hda_codec *codec,
 148                                struct hda_jack_tbl *jack)
 149 {
 150         if (!jack->jack_dirty)
 151                 return;
 152 
 153         if (jack->phantom_jack)
 154                 jack->pin_sense = AC_PINSENSE_PRESENCE;
 155         else
 156                 jack->pin_sense = read_pin_sense(codec, jack->nid);
 157 
 158         /* A gating jack indicates the jack is invalid if gating is unplugged */
 159         if (jack->gating_jack && !snd_hda_jack_detect(codec, jack->gating_jack))
 160                 jack->pin_sense &= ~AC_PINSENSE_PRESENCE;
 161 
 162         jack->jack_dirty = 0;
 163 
 164         /* If a jack is gated by this one update it. */
 165         if (jack->gated_jack) {
 166                 struct hda_jack_tbl *gated =
 167                         snd_hda_jack_tbl_get(codec, jack->gated_jack);
 168                 if (gated) {
 169                         gated->jack_dirty = 1;
 170                         jack_detect_update(codec, gated);
 171                 }
 172         }
 173 }
 174 
 175 /**
 176  * snd_hda_set_dirty_all - Mark all the cached as dirty
 177  * @codec: the HDA codec
 178  *
 179  * This function sets the dirty flag to all entries of jack table.
 180  * It's called from the resume path in hda_codec.c.
 181  */
 182 void snd_hda_jack_set_dirty_all(struct hda_codec *codec)
 183 {
 184         struct hda_jack_tbl *jack = codec->jacktbl.list;
 185         int i;
 186 
 187         for (i = 0; i < codec->jacktbl.used; i++, jack++)
 188                 if (jack->nid)
 189                         jack->jack_dirty = 1;
 190 }
 191 EXPORT_SYMBOL_GPL(snd_hda_jack_set_dirty_all);
 192 
 193 /**
 194  * snd_hda_pin_sense - execute pin sense measurement
 195  * @codec: the CODEC to sense
 196  * @nid: the pin NID to sense
 197  *
 198  * Execute necessary pin sense measurement and return its Presence Detect,
 199  * Impedance, ELD Valid etc. status bits.
 200  */
 201 u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
 202 {
 203         struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
 204         if (jack) {
 205                 jack_detect_update(codec, jack);
 206                 return jack->pin_sense;
 207         }
 208         return read_pin_sense(codec, nid);
 209 }
 210 EXPORT_SYMBOL_GPL(snd_hda_pin_sense);
 211 
 212 /**
 213  * snd_hda_jack_detect_state - query pin Presence Detect status
 214  * @codec: the CODEC to sense
 215  * @nid: the pin NID to sense
 216  *
 217  * Query and return the pin's Presence Detect status, as either
 218  * HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM.
 219  */
 220 int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid)
 221 {
 222         struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
 223         if (jack && jack->phantom_jack)
 224                 return HDA_JACK_PHANTOM;
 225         else if (snd_hda_pin_sense(codec, nid) & AC_PINSENSE_PRESENCE)
 226                 return HDA_JACK_PRESENT;
 227         else
 228                 return HDA_JACK_NOT_PRESENT;
 229 }
 230 EXPORT_SYMBOL_GPL(snd_hda_jack_detect_state);
 231 
 232 /**
 233  * snd_hda_jack_detect_enable - enable the jack-detection
 234  * @codec: the HDA codec
 235  * @nid: pin NID to enable
 236  * @func: callback function to register
 237  *
 238  * In the case of error, the return value will be a pointer embedded with
 239  * errno.  Check and handle the return value appropriately with standard
 240  * macros such as @IS_ERR() and @PTR_ERR().
 241  */
 242 struct hda_jack_callback *
 243 snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
 244                                     hda_jack_callback_fn func)
 245 {
 246         struct hda_jack_tbl *jack;
 247         struct hda_jack_callback *callback = NULL;
 248         int err;
 249 
 250         jack = snd_hda_jack_tbl_new(codec, nid);
 251         if (!jack)
 252                 return ERR_PTR(-ENOMEM);
 253         if (func) {
 254                 callback = kzalloc(sizeof(*callback), GFP_KERNEL);
 255                 if (!callback)
 256                         return ERR_PTR(-ENOMEM);
 257                 callback->func = func;
 258                 callback->nid = jack->nid;
 259                 callback->next = jack->callback;
 260                 jack->callback = callback;
 261         }
 262 
 263         if (jack->jack_detect)
 264                 return callback; /* already registered */
 265         jack->jack_detect = 1;
 266         if (codec->jackpoll_interval > 0)
 267                 return callback; /* No unsol if we're polling instead */
 268         err = snd_hda_codec_write_cache(codec, nid, 0,
 269                                          AC_VERB_SET_UNSOLICITED_ENABLE,
 270                                          AC_USRSP_EN | jack->tag);
 271         if (err < 0)
 272                 return ERR_PTR(err);
 273         return callback;
 274 }
 275 EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable_callback);
 276 
 277 /**
 278  * snd_hda_jack_detect_enable - Enable the jack detection on the given pin
 279  * @codec: the HDA codec
 280  * @nid: pin NID to enable jack detection
 281  *
 282  * Enable the jack detection with the default callback.  Returns zero if
 283  * successful or a negative error code.
 284  */
 285 int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid)
 286 {
 287         return PTR_ERR_OR_ZERO(snd_hda_jack_detect_enable_callback(codec, nid, NULL));
 288 }
 289 EXPORT_SYMBOL_GPL(snd_hda_jack_detect_enable);
 290 
 291 /**
 292  * snd_hda_jack_set_gating_jack - Set gating jack.
 293  * @codec: the HDA codec
 294  * @gated_nid: gated pin NID
 295  * @gating_nid: gating pin NID
 296  *
 297  * Indicates the gated jack is only valid when the gating jack is plugged.
 298  */
 299 int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
 300                                  hda_nid_t gating_nid)
 301 {
 302         struct hda_jack_tbl *gated = snd_hda_jack_tbl_new(codec, gated_nid);
 303         struct hda_jack_tbl *gating = snd_hda_jack_tbl_new(codec, gating_nid);
 304 
 305         if (!gated || !gating)
 306                 return -EINVAL;
 307 
 308         gated->gating_jack = gating_nid;
 309         gating->gated_jack = gated_nid;
 310 
 311         return 0;
 312 }
 313 EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack);
 314 
 315 /**
 316  * snd_hda_jack_report_sync - sync the states of all jacks and report if changed
 317  * @codec: the HDA codec
 318  */
 319 void snd_hda_jack_report_sync(struct hda_codec *codec)
 320 {
 321         struct hda_jack_tbl *jack;
 322         int i, state;
 323 
 324         /* update all jacks at first */
 325         jack = codec->jacktbl.list;
 326         for (i = 0; i < codec->jacktbl.used; i++, jack++)
 327                 if (jack->nid)
 328                         jack_detect_update(codec, jack);
 329 
 330         /* report the updated jacks; it's done after updating all jacks
 331          * to make sure that all gating jacks properly have been set
 332          */
 333         jack = codec->jacktbl.list;
 334         for (i = 0; i < codec->jacktbl.used; i++, jack++)
 335                 if (jack->nid) {
 336                         if (!jack->jack || jack->block_report)
 337                                 continue;
 338                         state = jack->button_state;
 339                         if (get_jack_plug_state(jack->pin_sense))
 340                                 state |= jack->type;
 341                         snd_jack_report(jack->jack, state);
 342                         if (jack->button_state) {
 343                                 snd_jack_report(jack->jack,
 344                                                 state & ~jack->button_state);
 345                                 jack->button_state = 0; /* button released */
 346                         }
 347                 }
 348 }
 349 EXPORT_SYMBOL_GPL(snd_hda_jack_report_sync);
 350 
 351 /* guess the jack type from the pin-config */
 352 static int get_input_jack_type(struct hda_codec *codec, hda_nid_t nid)
 353 {
 354         unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
 355         switch (get_defcfg_device(def_conf)) {
 356         case AC_JACK_LINE_OUT:
 357         case AC_JACK_SPEAKER:
 358                 return SND_JACK_LINEOUT;
 359         case AC_JACK_HP_OUT:
 360                 return SND_JACK_HEADPHONE;
 361         case AC_JACK_SPDIF_OUT:
 362         case AC_JACK_DIG_OTHER_OUT:
 363                 return SND_JACK_AVOUT;
 364         case AC_JACK_MIC_IN:
 365                 return SND_JACK_MICROPHONE;
 366         default:
 367                 return SND_JACK_LINEIN;
 368         }
 369 }
 370 
 371 static void hda_free_jack_priv(struct snd_jack *jack)
 372 {
 373         struct hda_jack_tbl *jacks = jack->private_data;
 374         jacks->nid = 0;
 375         jacks->jack = NULL;
 376 }
 377 
 378 /**
 379  * snd_hda_jack_add_kctl - Add a kctl for the given pin
 380  * @codec: the HDA codec
 381  * @nid: pin NID to assign
 382  * @name: string name for the jack
 383  * @phantom_jack: flag to deal as a phantom jack
 384  * @type: jack type bits to be reported, 0 for guessing from pincfg
 385  * @keymap: optional jack / key mapping
 386  *
 387  * This assigns a jack-detection kctl to the given pin.  The kcontrol
 388  * will have the given name and index.
 389  */
 390 int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
 391                           const char *name, bool phantom_jack,
 392                           int type, const struct hda_jack_keymap *keymap)
 393 {
 394         struct hda_jack_tbl *jack;
 395         const struct hda_jack_keymap *map;
 396         int err, state, buttons;
 397 
 398         jack = snd_hda_jack_tbl_new(codec, nid);
 399         if (!jack)
 400                 return 0;
 401         if (jack->jack)
 402                 return 0; /* already created */
 403 
 404         if (!type)
 405                 type = get_input_jack_type(codec, nid);
 406 
 407         buttons = 0;
 408         if (keymap) {
 409                 for (map = keymap; map->type; map++)
 410                         buttons |= map->type;
 411         }
 412 
 413         err = snd_jack_new(codec->card, name, type | buttons,
 414                            &jack->jack, true, phantom_jack);
 415         if (err < 0)
 416                 return err;
 417 
 418         jack->phantom_jack = !!phantom_jack;
 419         jack->type = type;
 420         jack->button_state = 0;
 421         jack->jack->private_data = jack;
 422         jack->jack->private_free = hda_free_jack_priv;
 423         if (keymap) {
 424                 for (map = keymap; map->type; map++)
 425                         snd_jack_set_key(jack->jack, map->type, map->key);
 426         }
 427 
 428         state = snd_hda_jack_detect(codec, nid);
 429         snd_jack_report(jack->jack, state ? jack->type : 0);
 430 
 431         return 0;
 432 }
 433 EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl);
 434 
 435 static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
 436                          const struct auto_pin_cfg *cfg,
 437                          const char *base_name)
 438 {
 439         unsigned int def_conf, conn;
 440         char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 441         int err;
 442         bool phantom_jack;
 443 
 444         if (!nid)
 445                 return 0;
 446         def_conf = snd_hda_codec_get_pincfg(codec, nid);
 447         conn = get_defcfg_connect(def_conf);
 448         if (conn == AC_JACK_PORT_NONE)
 449                 return 0;
 450         phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
 451                        !is_jack_detectable(codec, nid);
 452 
 453         if (base_name)
 454                 strlcpy(name, base_name, sizeof(name));
 455         else
 456                 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), NULL);
 457         if (phantom_jack)
 458                 /* Example final name: "Internal Mic Phantom Jack" */
 459                 strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
 460         err = snd_hda_jack_add_kctl(codec, nid, name, phantom_jack, 0, NULL);
 461         if (err < 0)
 462                 return err;
 463 
 464         if (!phantom_jack)
 465                 return snd_hda_jack_detect_enable(codec, nid);
 466         return 0;
 467 }
 468 
 469 /**
 470  * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg
 471  * @codec: the HDA codec
 472  * @cfg: pin config table to parse
 473  */
 474 int snd_hda_jack_add_kctls(struct hda_codec *codec,
 475                            const struct auto_pin_cfg *cfg)
 476 {
 477         const hda_nid_t *p;
 478         int i, err;
 479 
 480         for (i = 0; i < cfg->num_inputs; i++) {
 481                 /* If we have headphone mics; make sure they get the right name
 482                    before grabbed by output pins */
 483                 if (cfg->inputs[i].is_headphone_mic) {
 484                         if (auto_cfg_hp_outs(cfg) == 1)
 485                                 err = add_jack_kctl(codec, auto_cfg_hp_pins(cfg)[0],
 486                                                     cfg, "Headphone Mic");
 487                         else
 488                                 err = add_jack_kctl(codec, cfg->inputs[i].pin,
 489                                                     cfg, "Headphone Mic");
 490                 } else
 491                         err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg,
 492                                             NULL);
 493                 if (err < 0)
 494                         return err;
 495         }
 496 
 497         for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
 498                 err = add_jack_kctl(codec, *p, cfg, NULL);
 499                 if (err < 0)
 500                         return err;
 501         }
 502         for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
 503                 if (*p == *cfg->line_out_pins) /* might be duplicated */
 504                         break;
 505                 err = add_jack_kctl(codec, *p, cfg, NULL);
 506                 if (err < 0)
 507                         return err;
 508         }
 509         for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
 510                 if (*p == *cfg->line_out_pins) /* might be duplicated */
 511                         break;
 512                 err = add_jack_kctl(codec, *p, cfg, NULL);
 513                 if (err < 0)
 514                         return err;
 515         }
 516         for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
 517                 err = add_jack_kctl(codec, *p, cfg, NULL);
 518                 if (err < 0)
 519                         return err;
 520         }
 521         err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, NULL);
 522         if (err < 0)
 523                 return err;
 524         err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, NULL);
 525         if (err < 0)
 526                 return err;
 527         return 0;
 528 }
 529 EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctls);
 530 
 531 static void call_jack_callback(struct hda_codec *codec, unsigned int res,
 532                                struct hda_jack_tbl *jack)
 533 {
 534         struct hda_jack_callback *cb;
 535 
 536         for (cb = jack->callback; cb; cb = cb->next) {
 537                 cb->jack = jack;
 538                 cb->unsol_res = res;
 539                 cb->func(codec, cb);
 540         }
 541         if (jack->gated_jack) {
 542                 struct hda_jack_tbl *gated =
 543                         snd_hda_jack_tbl_get(codec, jack->gated_jack);
 544                 if (gated) {
 545                         for (cb = gated->callback; cb; cb = cb->next) {
 546                                 cb->jack = gated;
 547                                 cb->unsol_res = res;
 548                                 cb->func(codec, cb);
 549                         }
 550                 }
 551         }
 552 }
 553 
 554 /**
 555  * snd_hda_jack_unsol_event - Handle an unsolicited event
 556  * @codec: the HDA codec
 557  * @res: the unsolicited event data
 558  */
 559 void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
 560 {
 561         struct hda_jack_tbl *event;
 562         int tag = (res & AC_UNSOL_RES_TAG) >> AC_UNSOL_RES_TAG_SHIFT;
 563 
 564         event = snd_hda_jack_tbl_get_from_tag(codec, tag);
 565         if (!event)
 566                 return;
 567         event->jack_dirty = 1;
 568 
 569         call_jack_callback(codec, res, event);
 570         snd_hda_jack_report_sync(codec);
 571 }
 572 EXPORT_SYMBOL_GPL(snd_hda_jack_unsol_event);
 573 
 574 /**
 575  * snd_hda_jack_poll_all - Poll all jacks
 576  * @codec: the HDA codec
 577  *
 578  * Poll all detectable jacks with dirty flag, update the status, call
 579  * callbacks and call snd_hda_jack_report_sync() if any changes are found.
 580  */
 581 void snd_hda_jack_poll_all(struct hda_codec *codec)
 582 {
 583         struct hda_jack_tbl *jack = codec->jacktbl.list;
 584         int i, changes = 0;
 585 
 586         for (i = 0; i < codec->jacktbl.used; i++, jack++) {
 587                 unsigned int old_sense;
 588                 if (!jack->nid || !jack->jack_dirty || jack->phantom_jack)
 589                         continue;
 590                 old_sense = get_jack_plug_state(jack->pin_sense);
 591                 jack_detect_update(codec, jack);
 592                 if (old_sense == get_jack_plug_state(jack->pin_sense))
 593                         continue;
 594                 changes = 1;
 595                 call_jack_callback(codec, 0, jack);
 596         }
 597         if (changes)
 598                 snd_hda_jack_report_sync(codec);
 599 }
 600 EXPORT_SYMBOL_GPL(snd_hda_jack_poll_all);
 601 

/* [<][>][^][v][top][bottom][index][help] */