static void max14688_det_work (struct work_struct *work) { struct max14688 *me = container_of(work, struct max14688, det_work.work); int micZ, leftZ; if(earjack_detect == true) { log_dbg("duplication intterupt already connect earjack\n"); return; } else { earjack_detect = true; } __lock(me); if (unlikely(!me->detect_jack(me->dev))) { log_warn("no jack in detection work\n"); earjack_detect = false; goto out; } max14688_update_status(me); /* Read MIC and L-line impedences */ micZ = me->read_mic_impedence(me->dev); leftZ = me->read_left_impedence(me->dev); log_dbg("%s[micZ = %d, leftZ = %d\n", __func__, micZ, leftZ); /* Look up jack matching impedence ranges */ max14688_lookup_jack(me, micZ, leftZ); if (unlikely(!__present_valid_jack(me))) { earjack_detect = false; goto no_match_found; } max14688_write_mode0(me, __current_jack_mode0(me)); max14688_write_mode1(me, __current_jack_mode1(me)); if (__current_jack_has_button(me)) { max14688_enable_irq(me, IRQ_SWD); } else { max14688_disable_irq(me, IRQ_SWD); } log_dbg("jack %s inserted\n", __current_jack_name(me)); me->report_jack(me->dev, __current_jack(me), JACK_IN_VALUE); goto out; no_match_found: /* Handle exception */ log_err("unknown jack - mic %d, left %d\n", micZ, leftZ); out: __unlock(me); return; }
static ssize_t max14688_status_store (struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct max14688 *me = dev_get_drvdata(dev); __lock(me); max14688_update_status(me); __unlock(me); return (ssize_t)count; }
static bool max14688_detect_jack (struct device *dev) { struct max14688 *me = dev_get_drvdata(dev); int rc; rc = max14688_update_status(me); if (unlikely(rc)) { return false; } return (max14688_get_status(me, STATUS_DET) == 0); }
static void max14688_irq_work (struct work_struct *work) { struct max14688 *me = container_of(work, struct max14688, irq_work.work); bool jack_detected, button_pressed; u8 irq_bits; u8 irq_current = 0; int rc; log_dbg("%s\n", __func__); rc = max14688_read(me, INTERRUPT, &irq_current); if (unlikely(rc)) { log_err("INTERRUPT read error [%d]\n", rc); goto out; } me->irq_saved |= irq_current; log_dbg("INTERRUPT CURR %02X SAVED %02X EN %02X\n", irq_current, me->irq_saved, me->irq_unmask); __lock(me); /* re-new status */ max14688_update_status(me); spin_lock(&me->irq_lock); log_dbg("%s[me->irq_saved = %d, me->irq_unmask = %d\n", __func__, me->irq_saved, me->irq_unmask); irq_bits = me->irq_saved & me->irq_unmask; me->irq_saved = 0; spin_unlock(&me->irq_lock); jack_detected = me->detect_jack(me->dev); button_pressed = (max14688_get_status(me, STATUS_SWD) != 0); log_dbg("%s[jack_detected = %d]\n", __func__, jack_detected); if (likely(irq_bits & IRQ_DET)) { /* jack insert/remove irq */ if (jack_detected) { max14688_irq_jack_inserted(me); } else { max14688_irq_jack_removed(me); } } if (unlikely(!jack_detected)) { goto out; } if (likely(irq_bits & IRQ_SWD)) { /* button press/release irq */ if (button_pressed) { max14688_irq_button_pressed(me); } else { max14688_irq_button_released(me); } } out: if (unlikely(me->irq < 0)) { schedule_delayed_work(&me->irq_work, usecs_to_jiffies(MAX14688_POLLMODE_INTERVAL)); } __unlock(me); return; }