示例#1
0
static void max14688_irq_jack_inserted (struct max14688 *me)
{
	unsigned long det_work_delay = msecs_to_jiffies(500);

#ifdef CONFIG_LGE_EARJACK_DEBUGGER
	msm_serial_set_uart_console(lge_uart_console_should_enable_on_default());
#endif

	/* Check INT bit and STATUS_INT bit for avoiding JIG mode */
	if (unlikely(max14688_get_status(me, STATUS_INT) && max14688_get_status(me, STATUS_MICIN))) {
		log_info("JIG power detected\n");

		max14688_disable_irq(me, IRQ_SWD);
#ifdef CONFIG_LGE_EARJACK_DEBUGGER
		msm_serial_set_uart_console(lge_uart_console_should_enable_on_earjack_debugger());
#endif
		me->matched_jack   = -1;
		me->matched_button = -1;
		goto out;
	}

	if (unlikely(__present_valid_jack(me))) {
		log_warn("new jack detected during insertion of jack %s\n",
				__current_jack_name(me));
#ifdef MAX14688_OVERWRITE_JACK_INSERTION
		max14688_irq_jack_removed(me);
#else
		goto out;
#endif
	}

	if (unlikely(delayed_work_pending(&me->det_work))) {
		log_warn("detection in progress\n");
		goto out;
	}

	log_dbg("%s\n", __func__);
	max14688_write_mode0(me, MAX14688_MODE_HIGH);
	max14688_write_mode1(me, MAX14688_MODE_LOW);

	schedule_delayed_work(&me->det_work, det_work_delay);

out:
	return;
}
示例#2
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);
}
示例#3
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;
}
static __devinit int max14688_probe (struct i2c_client *client,
    const struct i2c_device_id *id)
{
    struct max14688_platform_data *pdata = client->dev.platform_data;
    struct max14688 *me;
    u8 chip_id, chip_rev;
    int i, rc;
    u8 pincontrol2 = 0;

    log_dbg(MAX14688_NAME" attached\n");

    log_dbg("wake_lock_init\n");
    wake_lock_init(&ear_key_wake_lock, WAKE_LOCK_SUSPEND, "ear_key");

    me = kzalloc(sizeof(struct max14688), GFP_KERNEL);

    if (me == NULL) {
	    log_err("Failed to allloate headset per device info\n");
	    return -ENOMEM;
    }

    if (client->dev.of_node) {
	    pdata = devm_kzalloc(&client->dev, sizeof(struct max14688_platform_data), GFP_KERNEL);
	    if (unlikely(!pdata)) {
		    log_err("out of memory (%uB requested)\n", sizeof(struct max14688_platform_data));
		    return -ENOMEM;
	    }
	    client->dev.platform_data = pdata;

	    max14688_parse_dt(&client->dev, pdata);
    } else {
	    pdata = devm_kzalloc(&client->dev, sizeof(struct max14688_platform_data), GFP_KERNEL);
	    if (unlikely(!pdata)) {
		    log_err("out of memory (%uB requested)\n", sizeof(struct max14688_platform_data));
		    return -ENOMEM;
	    } else {
		    pdata = client->dev.platform_data;
	    }
    }

    i2c_set_clientdata(client, me);

    spin_lock_init(&me->irq_lock);
    mutex_init(&me->lock);
    me->dev  = &client->dev;
    me->kobj = &client->dev.kobj;
    me->irq  = -1;

    me->gpio_int = pdata->gpio_int;
    me->gpio_detect = pdata->gpio_detect;

    INIT_DELAYED_WORK(&me->irq_work, max14688_irq_work);
    INIT_DELAYED_WORK(&me->det_work, max14688_det_work);
#ifdef I2C_SUSPEND_WORKAROUND
    INIT_DELAYED_WORK(&me->check_suspended_work, max14688_check_suspended_worker);
#endif

    rc = gpio_request(me->gpio_detect, MAX14688_NAME"-detect");
    if (unlikely(rc)) {
	    return rc;
    }

    rc = gpio_direction_input(me->gpio_detect);
    if (rc < 0) {
	    log_err("Failed to configure gpio%d (me->gpio_detect) gpio_direction_input\n", me->gpio_detect);
	    gpio_free(me->gpio_detect);
	    return rc;
    }

    rc = gpio_request(me->gpio_int, MAX14688_NAME"-irq");
    if (unlikely(rc)) {
	    return rc;
    }

    rc = gpio_direction_input(me->gpio_int);
    if (rc < 0) {
	    log_err("Failed to configure gpio%d (me->gpio_int) gpio_direction_input\n", me->gpio_int);
	    gpio_free(me->gpio_int);
	    return rc;
    }

    me->irq = gpio_to_irq(me->gpio_int);

    /* Save jack lookup table given via platform data */
    me->jack_matches        = pdata->jack_matches;
    me->num_of_jack_matches = pdata->num_of_jack_matches;

    /* Save button lookup table given via platform data */
    me->button_matches        = pdata->button_matches;
    me->num_of_button_matches = pdata->num_of_button_matches;

    me->matched_jack   = -1;
    me->matched_button = -1;

    /* Platform-specific Calls */
    me->detect_jack = pdata->detect_jack;
    me->read_mic_impedence = pdata->read_mic_impedence;
    me->read_left_impedence = pdata->read_left_impedence;
    me->report_jack = pdata->report_jack;
    me->report_button = pdata->report_button;

    /* Disable & Clear all interrupts */
    max14688_write(me, MASK, 0x00);
    max14688_read(me, INTERRUPT, &me->irq_saved);

    /* INT AUTO disable(INT follows the state diagram and flow chart) */
    max14688_read(me, PINCONTROL2, &pincontrol2);
    max14688_write(me, PINCONTROL2, ~PINCONTROL2_INTAUTO & pincontrol2);
    max14688_read(me, PINCONTROL2, &pincontrol2);

    log_dbg("%s[pincontrol2 = %d]\n", __func__, pincontrol2);

    /* Default MODE setting */
    max14688_write_mode0(me, MAX14688_MODE_LOW);
    max14688_write_mode1(me, MAX14688_MODE_LOW);

    me->irq_saved = 0;
    me->irq_unmask = 0;

    log_dbg("%s[me->irq_saved = %d]\n", __func__, me->irq_saved);

    /* Register input_dev */
    me->input_dev = input_allocate_device();
    if (unlikely(!me->input_dev)) {
	    log_err("failed to allocate memory for new input device\n");
	    rc = -ENOMEM;
	    goto abort;
    }
    /* initialize switch device */
    me->sdev.name             = pdata->switch_name;

    rc = switch_dev_register(&me->sdev);

    if (rc < 0) {
	    log_err("Failed to register switch device\n");
	    switch_dev_unregister(&me->sdev);
	    goto abort;
    }

    me->input_dev->name       = DRIVER_NAME;
    me->input_dev->phys       = DRIVER_NAME"/input0";
    me->input_dev->dev.parent = me->dev;

    for (i = 0; i < me->num_of_jack_matches; i++) {
	    if (likely(me->jack_matches[i].evt_type < EV_MAX)) {
		    input_set_capability(me->input_dev,
				    me->jack_matches[i].evt_type, me->jack_matches[i].evt_code1);
		    if (likely(me->jack_matches[i].evt_code2))
			    input_set_capability(me->input_dev,
					    me->jack_matches[i].evt_type, me->jack_matches[i].evt_code2);
	    }
    }

    for (i = 0; i < me->num_of_button_matches; i++) {
	    if (likely(me->button_matches[i].evt_type < EV_MAX)) {
		    input_set_capability(me->input_dev,
				    me->button_matches[i].evt_type, me->button_matches[i].evt_code);
	    }
    }

    rc = input_register_device(me->input_dev);
    if (unlikely(rc)) {
	    log_err("failed to register input device [%d]\n", rc);
	    input_free_device(me->input_dev);
	    me->input_dev = NULL;
	    goto abort;
    }

    /* Create max14688 sysfs attributes */
    me->attr_grp = &max14688_attr_group;
    rc = sysfs_create_group(me->kobj, me->attr_grp);
    if (unlikely(rc)) {
	    log_err("failed to create attribute group [%d]\n", rc);
	    me->attr_grp = NULL;
	    goto abort;
    }

    /* Get MAX14688 IRQ */
    if (unlikely(me->irq < 0)) {
	    log_warn("interrupt disabled\n");
    } else {
	    /* Request system IRQ for MAX14688 */
	    rc = request_threaded_irq(me->irq, NULL, max14688_isr,
			    IRQF_ONESHOT | IRQF_TRIGGER_FALLING, DRIVER_NAME, me);
	    if (unlikely(rc < 0)) {
		    log_err("failed to request IRQ(%u) [%d]\n", me->irq, rc);
		    me->irq = -1;
		    goto abort;
	    }
	    disable_irq((unsigned int)me->irq);
    }

    max14688_enable_irq(me, IRQ_DET);

    /* Complete initialization */

    log_info(DRIVER_DESC" "DRIVER_VERSION" Installed\n");

    chip_id  = 0;
    chip_rev = 0;
    max14688_read_device_id(me, &chip_id, &chip_rev);
    log_info("chip id %02X rev %02X\n", chip_id, chip_rev);

#ifdef CONFIG_EARJACK_DEBUGGER
    if (lge_get_board_revno() < HW_REV_1_0) {
	    if (!(max14688_get_status(me, STATUS_INT) && max14688_get_status(me, STATUS_MICIN))) {
		log_info("not connecting earjack debugger\n");
		msm_serial_set_uart_console(0);
	}
    }
#endif
    if (me->detect_jack(me->dev)) {
	max14688_irq_jack_inserted(me);
    }

    return 0;

abort:
    i2c_set_clientdata(client, NULL);
    max14688_destroy(me);
    return rc;
}