Exemple #1
0
/* must be called with ts->mutex held */
static void __tsc200x_disable(struct tsc200x *ts)
{
    tsc200x_stop_scan(ts);

    disable_irq(ts->irq);
    del_timer_sync(&ts->penup_timer);

    cancel_delayed_work_sync(&ts->esd_work);

    enable_irq(ts->irq);
}
Exemple #2
0
int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
                  struct regmap *regmap,
                  int (*tsc200x_cmd)(struct device *dev, u8 cmd))
{
    const struct tsc2005_platform_data *pdata = dev_get_platdata(dev);
    struct device_node *np = dev->of_node;

    struct tsc200x *ts;
    struct input_dev *input_dev;
    unsigned int max_x = MAX_12BIT;
    unsigned int max_y = MAX_12BIT;
    unsigned int max_p = MAX_12BIT;
    unsigned int fudge_x = TSC200X_DEF_X_FUZZ;
    unsigned int fudge_y = TSC200X_DEF_Y_FUZZ;
    unsigned int fudge_p = TSC200X_DEF_P_FUZZ;
    unsigned int x_plate_ohm = TSC200X_DEF_RESISTOR;
    unsigned int esd_timeout;
    int error;

    if (!np && !pdata) {
        dev_err(dev, "no platform data\n");
        return -ENODEV;
    }

    if (irq <= 0) {
        dev_err(dev, "no irq\n");
        return -ENODEV;
    }

    if (IS_ERR(regmap))
        return PTR_ERR(regmap);

    if (!tsc200x_cmd) {
        dev_err(dev, "no cmd function\n");
        return -ENODEV;
    }

    if (pdata) {
        fudge_x	= pdata->ts_x_fudge;
        fudge_y	= pdata->ts_y_fudge;
        fudge_p	= pdata->ts_pressure_fudge;
        max_x	= pdata->ts_x_max;
        max_y	= pdata->ts_y_max;
        max_p	= pdata->ts_pressure_max;
        x_plate_ohm = pdata->ts_x_plate_ohm;
        esd_timeout = pdata->esd_timeout_ms;
    } else {
        x_plate_ohm = TSC200X_DEF_RESISTOR;
        of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm);
        esd_timeout = 0;
        of_property_read_u32(np, "ti,esd-recovery-timeout-ms",
                             &esd_timeout);
    }

    ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
    if (!ts)
        return -ENOMEM;

    input_dev = devm_input_allocate_device(dev);
    if (!input_dev)
        return -ENOMEM;

    ts->irq = irq;
    ts->dev = dev;
    ts->idev = input_dev;
    ts->regmap = regmap;
    ts->tsc200x_cmd = tsc200x_cmd;
    ts->x_plate_ohm = x_plate_ohm;
    ts->esd_timeout = esd_timeout;

    ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
    if (IS_ERR(ts->reset_gpio)) {
        error = PTR_ERR(ts->reset_gpio);
        dev_err(dev, "error acquiring reset gpio: %d\n", error);
        return error;
    }

    ts->vio = devm_regulator_get_optional(dev, "vio");
    if (IS_ERR(ts->vio)) {
        error = PTR_ERR(ts->vio);
        dev_err(dev, "vio regulator missing (%d)", error);
        return error;
    }

    if (!ts->reset_gpio && pdata)
        ts->set_reset = pdata->set_reset;

    mutex_init(&ts->mutex);

    spin_lock_init(&ts->lock);
    setup_timer(&ts->penup_timer, tsc200x_penup_timer, (unsigned long)ts);

    INIT_DELAYED_WORK(&ts->esd_work, tsc200x_esd_work);

    snprintf(ts->phys, sizeof(ts->phys),
             "%s/input-ts", dev_name(dev));

    if (tsc_id->product == 2004) {
        input_dev->name = "TSC200X touchscreen";
    } else {
        input_dev->name = devm_kasprintf(dev, GFP_KERNEL,
                                         "TSC%04d touchscreen",
                                         tsc_id->product);
        if (!input_dev->name)
            return -ENOMEM;
    }

    input_dev->phys = ts->phys;
    input_dev->id = *tsc_id;
    input_dev->dev.parent = dev;
    input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
    input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

    input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0);
    input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0);
    input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);

    if (np)
        touchscreen_parse_properties(input_dev, false, NULL);

    input_dev->open = tsc200x_open;
    input_dev->close = tsc200x_close;

    input_set_drvdata(input_dev, ts);

    /* Ensure the touchscreen is off */
    tsc200x_stop_scan(ts);

    error = devm_request_threaded_irq(dev, irq, NULL,
                                      tsc200x_irq_thread,
                                      IRQF_TRIGGER_RISING | IRQF_ONESHOT,
                                      "tsc200x", ts);
    if (error) {
        dev_err(dev, "Failed to request irq, err: %d\n", error);
        return error;
    }

    /* enable regulator for DT */
    if (ts->vio) {
        error = regulator_enable(ts->vio);
        if (error)
            return error;
    }

    dev_set_drvdata(dev, ts);
    error = sysfs_create_group(&dev->kobj, &tsc200x_attr_group);
    if (error) {
        dev_err(dev,
                "Failed to create sysfs attributes, err: %d\n", error);
        goto disable_regulator;
    }

    error = input_register_device(ts->idev);
    if (error) {
        dev_err(dev,
                "Failed to register input device, err: %d\n", error);
        goto err_remove_sysfs;
    }

    irq_set_irq_wake(irq, 1);
    return 0;

err_remove_sysfs:
    sysfs_remove_group(&dev->kobj, &tsc200x_attr_group);
disable_regulator:
    if (ts->vio)
        regulator_disable(ts->vio);
    return error;
}
Exemple #3
0
int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
		  struct regmap *regmap,
		  int (*tsc200x_cmd)(struct device *dev, u8 cmd))
{
	struct tsc200x *ts;
	struct input_dev *input_dev;
	u32 x_plate_ohm;
	u32 esd_timeout;
	int error;

	if (irq <= 0) {
		dev_err(dev, "no irq\n");
		return -ENODEV;
	}

	if (IS_ERR(regmap))
		return PTR_ERR(regmap);

	if (!tsc200x_cmd) {
		dev_err(dev, "no cmd function\n");
		return -ENODEV;
	}

	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
	if (!ts)
		return -ENOMEM;

	input_dev = devm_input_allocate_device(dev);
	if (!input_dev)
		return -ENOMEM;

	ts->irq = irq;
	ts->dev = dev;
	ts->idev = input_dev;
	ts->regmap = regmap;
	ts->tsc200x_cmd = tsc200x_cmd;

	error = device_property_read_u32(dev, "ti,x-plate-ohms", &x_plate_ohm);
	ts->x_plate_ohm = error ? TSC200X_DEF_RESISTOR : x_plate_ohm;

	error = device_property_read_u32(dev, "ti,esd-recovery-timeout-ms",
					 &esd_timeout);
	ts->esd_timeout = error ? 0 : esd_timeout;

	ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
	if (IS_ERR(ts->reset_gpio)) {
		error = PTR_ERR(ts->reset_gpio);
		dev_err(dev, "error acquiring reset gpio: %d\n", error);
		return error;
	}

	ts->vio = devm_regulator_get(dev, "vio");
	if (IS_ERR(ts->vio)) {
		error = PTR_ERR(ts->vio);
		dev_err(dev, "error acquiring vio regulator: %d", error);
		return error;
	}

	mutex_init(&ts->mutex);

	spin_lock_init(&ts->lock);
	setup_timer(&ts->penup_timer, tsc200x_penup_timer, (unsigned long)ts);

	INIT_DELAYED_WORK(&ts->esd_work, tsc200x_esd_work);

	snprintf(ts->phys, sizeof(ts->phys),
		 "%s/input-ts", dev_name(dev));

	if (tsc_id->product == 2004) {
		input_dev->name = "TSC200X touchscreen";
	} else {
		input_dev->name = devm_kasprintf(dev, GFP_KERNEL,
						 "TSC%04d touchscreen",
						 tsc_id->product);
		if (!input_dev->name)
			return -ENOMEM;
	}

	input_dev->phys = ts->phys;
	input_dev->id = *tsc_id;

	input_dev->open = tsc200x_open;
	input_dev->close = tsc200x_close;

	input_set_drvdata(input_dev, ts);

	__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);

	input_set_abs_params(input_dev, ABS_X,
			     0, MAX_12BIT, TSC200X_DEF_X_FUZZ, 0);
	input_set_abs_params(input_dev, ABS_Y,
			     0, MAX_12BIT, TSC200X_DEF_Y_FUZZ, 0);
	input_set_abs_params(input_dev, ABS_PRESSURE,
			     0, MAX_12BIT, TSC200X_DEF_P_FUZZ, 0);

	touchscreen_parse_properties(input_dev, false, NULL);

	/* Ensure the touchscreen is off */
	tsc200x_stop_scan(ts);

	error = devm_request_threaded_irq(dev, irq, NULL,
					  tsc200x_irq_thread,
					  IRQF_TRIGGER_RISING | IRQF_ONESHOT,
					  "tsc200x", ts);
	if (error) {
		dev_err(dev, "Failed to request irq, err: %d\n", error);
		return error;
	}

	error = regulator_enable(ts->vio);
	if (error)
		return error;

	dev_set_drvdata(dev, ts);
	error = sysfs_create_group(&dev->kobj, &tsc200x_attr_group);
	if (error) {
		dev_err(dev,
			"Failed to create sysfs attributes, err: %d\n", error);
		goto disable_regulator;
	}

	error = input_register_device(ts->idev);
	if (error) {
		dev_err(dev,
			"Failed to register input device, err: %d\n", error);
		goto err_remove_sysfs;
	}

	irq_set_irq_wake(irq, 1);
	return 0;

err_remove_sysfs:
	sysfs_remove_group(&dev->kobj, &tsc200x_attr_group);
disable_regulator:
	regulator_disable(ts->vio);
	return error;
}