static void retu_headset_set_bias(int enable) { if (enable) { retu_set_clear_reg_bits(RETU_REG_AUDTXR, (1 << 0) | (1 << 1), 0); msleep(2); retu_set_clear_reg_bits(RETU_REG_AUDTXR, 1 << 3, 0); } else { retu_set_clear_reg_bits(RETU_REG_AUDTXR, 0, (1 << 0) | (1 << 1) | (1 << 3)); } }
static void retu_headset_enable_timer(unsigned long arg) { struct retu_headset *hs = (struct retu_headset *) arg; retu_set_clear_reg_bits(RETU_REG_CC1, (1 << 10) | (1 << 8), 0); mod_timer(&hs->detect_timer, jiffies + msecs_to_jiffies(350)); }
static void retu_headset_det_enable(struct retu_headset *hs) { mutex_lock(&hs->mutex); if (!hs->detection_enabled) { hs->detection_enabled = 1; retu_set_clear_reg_bits(RETU_REG_CC1, (1 << 10) | (1 << 8), 0); retu_enable_irq(RETU_INT_HOOK); } mutex_unlock(&hs->mutex); }
static void retu_headset_hook_interrupt(unsigned long arg) { struct retu_headset *hs = (struct retu_headset *) arg; unsigned long flags; retu_ack_irq(RETU_INT_HOOK); spin_lock_irqsave(&hs->lock, flags); if (!hs->pressed) { /* Headset button was just pressed down. */ hs->pressed = 1; input_report_key(hs->idev, RETU_HEADSET_KEY, 1); } spin_unlock_irqrestore(&hs->lock, flags); retu_set_clear_reg_bits(RETU_REG_CC1, 0, (1 << 10) | (1 << 8)); mod_timer(&hs->enable_timer, jiffies + msecs_to_jiffies(50)); }
static void retu_headset_det_disable(struct retu_headset *hs) { unsigned long flags; mutex_lock(&hs->mutex); if (hs->detection_enabled) { hs->detection_enabled = 0; retu_disable_irq(RETU_INT_HOOK); del_timer_sync(&hs->enable_timer); del_timer_sync(&hs->detect_timer); spin_lock_irqsave(&hs->lock, flags); if (hs->pressed) input_report_key(hs->idev, RETU_HEADSET_KEY, 0); spin_unlock_irqrestore(&hs->lock, flags); retu_set_clear_reg_bits(RETU_REG_CC1, 0, (1 << 10) | (1 << 8)); } mutex_unlock(&hs->mutex); }
static irqreturn_t retu_headset_hook_interrupt(int irq, void *_hs) { struct retu_headset *hs = _hs; unsigned long flags; spin_lock_irqsave(&hs->lock, flags); if (!hs->pressed) { /* Headset button was just pressed down. */ hs->pressed = 1; input_report_key(hs->idev, RETU_HEADSET_KEY, 1); } spin_unlock_irqrestore(&hs->lock, flags); retu_set_clear_reg_bits(hs->dev, RETU_REG_CC1, 0, (1 << 10) | (1 << 8)); mod_timer(&hs->enable_timer, jiffies + msecs_to_jiffies(50)); return IRQ_HANDLED; }