static void wacom_init_fw_algo(struct wacom_i2c *wac_i2c)
{
#if defined(CONFIG_MACH_T0)
	int digitizer_type = 0;

	/*Set data by digitizer type*/
	digitizer_type = wacom_i2c_get_digitizer_type();

	if (digitizer_type == EPEN_DTYPE_B746) {
		printk(KERN_DEBUG"epen:Use Box filter\n");
		wac_i2c->use_aveTransition = true;
	} else if (digitizer_type == EPEN_DTYPE_B713) {
		printk(KERN_DEBUG"epen:Reset tilt for B713\n");

		/*Change tuning version for B713*/
		tuning_version = tuning_version_B713;

		memcpy(tilt_offsetX, tilt_offsetX_B713, sizeof(tilt_offsetX));
		memcpy(tilt_offsetY, tilt_offsetY_B713, sizeof(tilt_offsetY));
	} else if (digitizer_type == EPEN_DTYPE_B660) {
		printk(KERN_DEBUG"epen:Reset tilt and origin for B660\n");

		origin_offset[0] = EPEN_B660_ORG_X;
		origin_offset[1] = EPEN_B660_ORG_Y;
		memset(tilt_offsetX, 0, sizeof(tilt_offsetX));
		memset(tilt_offsetY, 0, sizeof(tilt_offsetY));
		wac_i2c->use_offset_table = false;
	}

	/*Set switch type*/
	wac_i2c->invert_pen_insert = wacom_i2c_invert_by_switch_type();
#endif

}
Beispiel #2
0
static int wacom_i2c_probe(struct i2c_client *client,
                           const struct i2c_device_id *id)
{
    struct wacom_g5_platform_data *pdata = client->dev.platform_data;
    struct wacom_i2c *wac_i2c;
    struct input_dev *input;
    int ret = 0;
#if defined(CONFIG_MACH_T0)
    int digitizer_type = 0;
#endif

    firmware_updating_state = false;

    if (pdata == NULL) {
        printk(KERN_ERR "%s: no pdata\n", __func__);
        ret = -ENODEV;
        goto err_i2c_fail;
    }

    /*Check I2C functionality */
    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
        printk(KERN_ERR "[E-PEN] No I2C functionality found\n");
        ret = -ENODEV;
        goto err_i2c_fail;
    }

    /*Obtain kernel memory space for wacom i2c */
    wac_i2c = kzalloc(sizeof(struct wacom_i2c), GFP_KERNEL);
    if (NULL == wac_i2c) {
        printk(KERN_ERR "[E-PEN] failed to allocate wac_i2c.\n");
        ret = -ENOMEM;
        goto err_freemem;
    }

    wac_i2c->client_boot = i2c_new_dummy(client->adapter,
                                         WACOM_I2C_BOOT);
    if (!wac_i2c->client_boot) {
        dev_err(&client->dev, "Fail to register sub client[0x%x]\n",
                WACOM_I2C_BOOT);
    }

    input = input_allocate_device();
    if (NULL == input) {
        printk(KERN_ERR "[E-PEN] failed to allocate input device.\n");
        ret = -ENOMEM;
        goto err_input_allocate_device;
    } else
        wacom_i2c_set_input_values(client, wac_i2c, input);

    wac_i2c->wac_feature = &wacom_feature_EMR;
    wac_i2c->wac_pdata = pdata;
    wac_i2c->input_dev = input;
    wac_i2c->client = client;
    wac_i2c->irq = client->irq;
#ifdef WACOM_PDCT_WORK_AROUND
    wac_i2c->irq_pdct = gpio_to_irq(pdata->gpio_pendct);
#endif

#ifdef WACOM_PEN_DETECT
    wac_i2c->gpio_pen_insert = pdata->gpio_pen_insert;
#endif

#ifdef WACOM_HAVE_FWE_PIN
    wac_i2c->have_fwe_pin = true;
#ifdef CONFIG_MACH_T0
    if (system_rev < WACOM_FWE1_HWID)
        wac_i2c->have_fwe_pin = false;
#endif
#endif

    /*Change below if irq is needed */
    wac_i2c->irq_flag = 1;

    /*Register callbacks */
    wac_i2c->callbacks.check_prox = wacom_check_emr_prox;
    if (wac_i2c->wac_pdata->register_cb)
        wac_i2c->wac_pdata->register_cb(&wac_i2c->callbacks);

    /* Firmware Feature */
    wacom_i2c_init_firm_data();
#ifdef WACOM_IMPORT_FW_ALGO
    wac_i2c->use_offset_table = true;
    wac_i2c->use_aveTransition = false;
#endif

#if defined(CONFIG_MACH_Q1_BD)
    /* Change Origin offset by rev */
    if (system_rev < 6) {
        origin_offset[0] = origin_offset_48[0];
        origin_offset[1] = origin_offset_48[1];
    }
    /* Reset IC */
    wacom_i2c_reset_hw(wac_i2c->wac_pdata);
#elif defined(CONFIG_MACH_T0)
    wac_i2c->wac_pdata->late_resume_platform_hw();
    msleep(200);

    /*Set data by digitizer type*/
    digitizer_type = wacom_i2c_get_digitizer_type();

    if (digitizer_type == EPEN_DTYPE_B746) {
        printk(KERN_DEBUG"[E-PEN] Use Box filter\n");
        wac_i2c->use_aveTransition = true;
    } else if (digitizer_type == EPEN_DTYPE_B713) {
        printk(KERN_DEBUG"[E-PEN] Reset tilt for B713\n");

        /*Change tuning version for B713*/
        tuning_version = tuning_version_B713;

        memcpy(tilt_offsetX, tilt_offsetX_B713, sizeof(tilt_offsetX));
        memcpy(tilt_offsetY, tilt_offsetY_B713, sizeof(tilt_offsetY));
    } else if (digitizer_type == EPEN_DTYPE_B660) {
        printk(KERN_DEBUG"[E-PEN] Reset tilt and origin for B660\n");

        origin_offset[0] = EPEN_B660_ORG_X;
        origin_offset[1] = EPEN_B660_ORG_Y;
        memset(tilt_offsetX, 0, sizeof(tilt_offsetX));
        memset(tilt_offsetY, 0, sizeof(tilt_offsetY));
        wac_i2c->use_offset_table = false;
    }

    /*Set switch type*/
    wac_i2c->invert_pen_insert = wacom_i2c_invert_by_switch_type();
#elif defined(CONFIG_MACH_KONA)
    wac_i2c->wac_pdata->late_resume_platform_hw();
    msleep(200);
#endif
#ifdef WACOM_PDCT_WORK_AROUND
    wac_i2c->pen_pdct = PDCT_NOSIGNAL;
#endif

#if defined(CONFIG_MACH_P4NOTE)
    wac_i2c->wac_pdata->resume_platform_hw();
    msleep(200);
#endif
    wac_i2c->power_enable = true;

    ret = wacom_i2c_query(wac_i2c);

    if (ret < 0)
        epen_reset_result = false;
    else
        epen_reset_result = true;

#if defined(CONFIG_MACH_P4NOTE)
    input_set_abs_params(input, ABS_X, WACOM_POSX_OFFSET,
                         wac_i2c->wac_feature->x_max, 4, 0);
    input_set_abs_params(input, ABS_Y, WACOM_POSY_OFFSET,
                         wac_i2c->wac_feature->y_max, 4, 0);
    input_set_abs_params(input, ABS_PRESSURE, 0,
                         WACOM_MAX_PRESSURE, 0, 0);
#else
    input_set_abs_params(wac_i2c->input_dev, ABS_X, pdata->min_x,
                         pdata->max_x, 4, 0);
    input_set_abs_params(wac_i2c->input_dev, ABS_Y, pdata->min_y,
                         pdata->max_y, 4, 0);
#ifdef CONFIG_MACH_T0
    input_set_abs_params(wac_i2c->input_dev, ABS_PRESSURE,
                         0, wac_i2c->wac_feature->pressure_max, 0, 0);
#else
    input_set_abs_params(wac_i2c->input_dev, ABS_PRESSURE,
                         pdata->min_pressure, pdata->max_pressure, 0, 0);
#endif
#endif
    input_set_drvdata(input, wac_i2c);

    /*Before registering input device, data in each input_dev must be set */
    ret = input_register_device(input);
    if (ret) {
        pr_err("[E-PEN] failed to register input device.\n");
        goto err_register_device;
    }

    /*Change below if irq is needed */
    wac_i2c->irq_flag = 1;

    /*Set client data */
    i2c_set_clientdata(client, wac_i2c);
    i2c_set_clientdata(wac_i2c->client_boot, wac_i2c);

    /*Initializing for semaphor */
    mutex_init(&wac_i2c->lock);
    wake_lock_init(&wac_i2c->wakelock, WAKE_LOCK_SUSPEND, "wacom");
    INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work);
#if defined(WACOM_IRQ_WORK_AROUND)
    INIT_DELAYED_WORK(&wac_i2c->pendct_dwork, wacom_i2c_pendct_work);
#endif
#ifdef WACOM_STATE_CHECK
    INIT_DELAYED_WORK(&wac_i2c->wac_statecheck_work, wac_statecheck_work);
#endif


#ifdef CONFIG_HAS_EARLYSUSPEND
    wac_i2c->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
    wac_i2c->early_suspend.suspend = wacom_i2c_early_suspend;
    wac_i2c->early_suspend.resume = wacom_i2c_late_resume;
    register_early_suspend(&wac_i2c->early_suspend);
#endif

    wac_i2c->dev = device_create(sec_class, NULL, 0, NULL, "sec_epen");
    if (IS_ERR(wac_i2c->dev)) {
        printk(KERN_ERR "Failed to create device(wac_i2c->dev)!\n");
        goto err_sysfs_create_group;
    } else {
        dev_set_drvdata(wac_i2c->dev, wac_i2c);
        ret = sysfs_create_group(&wac_i2c->dev->kobj, &epen_attr_group);
        if (ret) {
            printk(KERN_ERR
                   "[E-PEN]: failed to create sysfs group\n");
            goto err_sysfs_create_group;
        }
    }

    /* firmware info */
    printk(KERN_NOTICE "[E-PEN] wacom fw ver : 0x%x, new fw ver : 0x%x\n",
           wac_i2c->wac_feature->fw_version, Firmware_version_of_file);

#ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK
    INIT_DELAYED_WORK(&wac_i2c->dvfs_work, free_dvfs_lock);
    if (exynos_cpufreq_get_level(WACOM_DVFS_LOCK_FREQ,
                                 &wac_i2c->cpufreq_level))
        printk(KERN_ERR "[E-PEN] exynos_cpufreq_get_level Error\n");
#ifdef SEC_BUS_LOCK
    wac_i2c->dvfs_lock_status = false;
#if defined(CONFIG_MACH_P4NOTE)
    wac_i2c->bus_dev = dev_get("exynos-busfreq");
#endif	/* CONFIG_MACH_P4NOTE */
#endif	/* SEC_BUS_LOCK */
#endif	/* CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK */

    /*Request IRQ */
    if (wac_i2c->irq_flag) {
        ret =
            request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt,
                                 IRQF_DISABLED | IRQF_TRIGGER_RISING |
                                 IRQF_ONESHOT, wac_i2c->name, wac_i2c);
        if (ret < 0) {
            printk(KERN_ERR
                   "[E-PEN] failed to request irq(%d) - %d\n",
                   wac_i2c->irq, ret);
            goto err_request_irq;
        }

#if defined(WACOM_PDCT_WORK_AROUND)
        ret =
            request_threaded_irq(wac_i2c->irq_pdct, NULL,
                                 wacom_interrupt_pdct,
                                 IRQF_DISABLED | IRQF_TRIGGER_RISING |
                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                 wac_i2c->name, wac_i2c);
        if (ret < 0) {
            printk(KERN_ERR
                   "[E-PEN] failed to request irq(%d) - %d\n",
                   wac_i2c->irq_pdct, ret);
            goto err_request_irq;
        }
#endif
    }

#ifdef WACOM_DEBOUNCEINT_BY_ESD
    /*Invert gpio value for  first irq.
        schedule_delayed_work in wacom_i2c_input_open*/
    pen_insert_state = gpio_get_value(wac_i2c->gpio_pen_insert);
    wac_i2c->pen_insert = pen_insert_state;
#if defined(CONFIG_MACH_T0)
    if (wac_i2c->invert_pen_insert) {
        wac_i2c->pen_insert = !wac_i2c->pen_insert;
        pen_insert_state = wac_i2c->pen_insert;
    }
#endif
#endif

    return 0;

err_request_irq:
err_sysfs_create_group:
err_register_device:
    input_unregister_device(input);
err_input_allocate_device:
    input_free_device(input);
err_freemem:
    kfree(wac_i2c);
err_i2c_fail:
    return ret;
}