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;
}
示例#2
0
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;
}
示例#3
0
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);
}
示例#4
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;
}