static int bu21013_resume(struct device *dev)
{
	struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev);
	struct i2c_client *client = bu21013_data->client;
	int retval;

	retval = regulator_enable(bu21013_data->regulator);
	if (retval < 0) {
		dev_err(&client->dev, "bu21013 regulator enable failed\n");
		return retval;
	}

	retval = bu21013_init_chip(bu21013_data);
	if (retval < 0) {
		dev_err(&client->dev, "bu21013 controller config failed\n");
		return retval;
	}

	bu21013_data->touch_stopped = false;

	if (device_may_wakeup(&client->dev))
		disable_irq_wake(bu21013_data->chip->irq);
	else
		enable_irq(bu21013_data->chip->irq);

	return 0;
}
/**
 * bu21013_enable() - enable the touch driver event
 * @pdata: touch screen data
 *
 * This function used to enable the driver and returns integer
 */
static int bu21013_enable(struct bu21013_ts_data *pdata)
{
	int retval;

	if (pdata->regulator)
		regulator_enable(pdata->regulator);

	if (pdata->chip->cs_en) {
		retval = pdata->chip->cs_en(pdata->chip->cs_pin);
		if (retval < 0) {
			dev_err(&pdata->client->dev, "enable hw failed\n");
			return retval;
		}
	}

	if (pdata->ext_clk_state)
		retval = bu21013_ext_clk(pdata, true, true);
	else
		retval = bu21013_init_chip(pdata, false);

	if (retval < 0) {
		dev_err(&pdata->client->dev, "enable hw failed\n");
		return retval;
	}
	pdata->touch_stopped = false;
	enable_irq(pdata->chip->irq);

	return 0;
}
/**
 * bu21013_ext_clk() - enable/disable the external clock
 * @pdata: touch screen data
 * @enable: enable external clock
 * @reconfig: reconfigure chip upon external clock off.
 *
 * This function used to enable or disable the external clock and possible
 * reconfigure hw.
 */
static int bu21013_ext_clk(struct bu21013_ts_data *pdata, bool enable,
			   bool reconfig)
{
	int retval = 0;

	if (!pdata->tpclk || pdata->ext_clk_enable == enable)
		return retval;

	if (enable) {
		pdata->ext_clk_enable = true;
		clk_enable(pdata->tpclk);
		retval = bu21013_init_chip(pdata, true);
	} else {
		pdata->ext_clk_enable = false;
		if (reconfig)
			retval = bu21013_init_chip(pdata, false);
		clk_disable(pdata->tpclk);
	}
	return retval;
}
static int __devinit bu21013_probe(struct i2c_client *client,
					const struct i2c_device_id *id)
{
	struct bu21013_ts_data *bu21013_data;
	struct input_dev *in_dev;
	const struct bu21013_platform_device *pdata =
					client->dev.platform_data;
	int error;

	if (!i2c_check_functionality(client->adapter,
					I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_err(&client->dev, "i2c smbus byte data not supported\n");
		return -EIO;
	}

	if (!pdata) {
		dev_err(&client->dev, "platform data not defined\n");
		return -EINVAL;
	}

	bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL);
	in_dev = input_allocate_device();
	if (!bu21013_data || !in_dev) {
		dev_err(&client->dev, "device memory alloc failed\n");
		error = -ENOMEM;
		goto err_free_mem;
	}

	bu21013_data->in_dev = in_dev;
	bu21013_data->chip = pdata;
	bu21013_data->client = client;

	bu21013_data->regulator = regulator_get(&client->dev, "V-TOUCH");
	if (IS_ERR(bu21013_data->regulator)) {
		dev_err(&client->dev, "regulator_get failed\n");
		error = PTR_ERR(bu21013_data->regulator);
		goto err_free_mem;
	}

	error = regulator_enable(bu21013_data->regulator);
	if (error < 0) {
		dev_err(&client->dev, "regulator enable failed\n");
		goto err_put_regulator;
	}

	bu21013_data->touch_stopped = false;
	init_waitqueue_head(&bu21013_data->wait);

	/*                         */
	if (pdata->cs_en) {
		error = pdata->cs_en(pdata->cs_pin);
		if (error < 0) {
			dev_err(&client->dev, "chip init failed\n");
			goto err_disable_regulator;
		}
	}

	/*                                      */
	error = bu21013_init_chip(bu21013_data);
	if (error) {
		dev_err(&client->dev, "error in bu21013 config\n");
		goto err_cs_disable;
	}

	/*                                        */
	in_dev->name = DRIVER_TP;
	in_dev->id.bustype = BUS_I2C;
	in_dev->dev.parent = &client->dev;

	__set_bit(EV_SYN, in_dev->evbit);
	__set_bit(EV_KEY, in_dev->evbit);
	__set_bit(EV_ABS, in_dev->evbit);

	input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0,
						pdata->touch_x_max, 0, 0);
	input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0,
						pdata->touch_y_max, 0, 0);
	input_set_drvdata(in_dev, bu21013_data);

	error = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq,
				     IRQF_TRIGGER_FALLING | IRQF_SHARED,
				     DRIVER_TP, bu21013_data);
	if (error) {
		dev_err(&client->dev, "request irq %d failed\n", pdata->irq);
		goto err_cs_disable;
	}

	error = input_register_device(in_dev);
	if (error) {
		dev_err(&client->dev, "failed to register input device\n");
		goto err_free_irq;
	}

	device_init_wakeup(&client->dev, pdata->wakeup);
	i2c_set_clientdata(client, bu21013_data);

	return 0;

err_free_irq:
	bu21013_free_irq(bu21013_data);
err_cs_disable:
	pdata->cs_dis(pdata->cs_pin);
err_disable_regulator:
	regulator_disable(bu21013_data->regulator);
err_put_regulator:
	regulator_put(bu21013_data->regulator);
err_free_mem:
	input_free_device(in_dev);
	kfree(bu21013_data);

	return error;
}
/**
 * bu21013_probe() - initialzes the i2c-client touchscreen driver
 * @client: i2c client structure pointer
 * @id: i2c device id pointer
 *
 * This function used to initializes the i2c-client touchscreen
 * driver and returns integer.
 */
static int __devinit bu21013_probe(struct i2c_client *client,
					const struct i2c_device_id *id)
{
	int retval;
	struct bu21013_ts_data *bu21013_data;
	struct input_dev *in_dev;
	struct bu21013_platform_device *pdata =
					client->dev.platform_data;

	if (!i2c_check_functionality(client->adapter,
					I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_err(&client->dev, "i2c smbus byte data not supported\n");
		return -EIO;
	}

	if (!pdata) {
		dev_err(&client->dev, "platform data not defined\n");
		retval = -EINVAL;
		return retval;
	}

	bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL);
	if (!bu21013_data) {
		dev_err(&client->dev, "device memory alloc failed\n");
		retval = -ENOMEM;
		return retval;
	}
	/* allocate input device */
	in_dev = input_allocate_device();
	if (!in_dev) {
		dev_err(&client->dev, "input device memory alloc failed\n");
		retval = -ENOMEM;
		goto err_alloc;
	}

	bu21013_data->in_dev = in_dev;
	bu21013_data->chip = pdata;
	bu21013_data->client = client;

	bu21013_data->regulator = regulator_get(&client->dev, "avdd");
	if (IS_ERR(bu21013_data->regulator)) {
		dev_warn(&client->dev, "regulator_get failed\n");
		bu21013_data->regulator = NULL;
	}
	if (bu21013_data->regulator)
		regulator_enable(bu21013_data->regulator);

	/* configure the gpio pins */
	if (pdata->cs_en) {
		retval = pdata->cs_en(pdata->cs_pin);
		if (retval < 0) {
			dev_err(&client->dev, "chip init failed\n");
			goto err_init_cs;
		}
	}

	if (pdata->has_ext_clk) {
		bu21013_data->tpclk = clk_get(&client->dev, NULL);
		if (IS_ERR(bu21013_data->tpclk)) {
			dev_warn(&client->dev, "get extern clock failed\n");
			bu21013_data->tpclk = NULL;
		}
	}

	if (pdata->enable_ext_clk && bu21013_data->tpclk) {
		retval = clk_enable(bu21013_data->tpclk);
		if (retval < 0) {
			dev_err(&client->dev, "clock enable failed\n");
			goto err_ext_clk;
		}
		bu21013_data->ext_clk_enable = true;
	}

	/* configure the touch panel controller */
	retval = bu21013_init_chip(bu21013_data, bu21013_data->ext_clk_enable);
	if (retval < 0) {
		dev_err(&client->dev, "error in bu21013 config\n");
		goto err_init_config;
	}

	init_waitqueue_head(&bu21013_data->wait);
	bu21013_data->touch_stopped = false;

	/* register the device to input subsystem */
	in_dev->name = DRIVER_TP;
	in_dev->id.bustype = BUS_I2C;
	in_dev->dev.parent = &client->dev;

	__set_bit(EV_SYN, in_dev->evbit);
	__set_bit(EV_KEY, in_dev->evbit);
	__set_bit(EV_ABS, in_dev->evbit);

	input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0,
						pdata->x_max_res, 0, 0);
	input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0,
						pdata->y_max_res, 0, 0);
	input_set_abs_params(in_dev, ABS_MT_TOUCH_MAJOR, 0,
			max(pdata->x_max_res , pdata->y_max_res), 0, 0);
	input_set_drvdata(in_dev, bu21013_data);
	retval = input_register_device(in_dev);
	if (retval)
		goto err_input_register;

	retval = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq,
					(IRQF_TRIGGER_FALLING | IRQF_SHARED),
					DRIVER_TP, bu21013_data);
	if (retval) {
		dev_err(&client->dev, "request irq %d failed\n", pdata->irq);
		goto err_init_irq;
	}
	bu21013_data->enable = true;
	i2c_set_clientdata(client, bu21013_data);

	/* sysfs implementation for dynamic enable/disable the input event */
	retval = sysfs_create_group(&client->dev.kobj,	&bu21013_attr_group);
	if (retval) {
		dev_err(&client->dev, "failed to create sysfs entries\n");
		goto err_sysfs_create;
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
	bu21013_data->early_suspend.level =
				EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	bu21013_data->early_suspend.suspend = bu21013_ts_early_suspend;
	bu21013_data->early_suspend.resume = bu21013_ts_late_resume;
	register_early_suspend(&bu21013_data->early_suspend);
#endif
	return retval;

err_sysfs_create:
	free_irq(pdata->irq, bu21013_data);
	i2c_set_clientdata(client, NULL);
err_init_irq:
	input_unregister_device(bu21013_data->in_dev);
err_input_register:
	wake_up(&bu21013_data->wait);
err_init_config:
	if (bu21013_data->tpclk) {
		if (bu21013_data->ext_clk_enable)
			clk_disable(bu21013_data->tpclk);
		clk_put(bu21013_data->tpclk);
	}
err_ext_clk:
	if (pdata->cs_dis)
		pdata->cs_dis(pdata->cs_pin);
err_init_cs:
	if (bu21013_data->regulator) {
		regulator_disable(bu21013_data->regulator);
		regulator_put(bu21013_data->regulator);
	}
	input_free_device(bu21013_data->in_dev);
err_alloc:
	kfree(bu21013_data);

	return retval;
}
Exemple #6
0
/**
 * bu21013_probe() - initializes the i2c-client touchscreen driver
 * @client: i2c client structure pointer
 * @id: i2c device id pointer
 *
 * This function used to initializes the i2c-client touchscreen
 * driver and returns integer.
 */
static int bu21013_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	const struct bu21013_platform_device *pdata =
					dev_get_platdata(&client->dev);
	struct bu21013_ts_data *bu21013_data;
	struct input_dev *in_dev;
	int error;

	if (!i2c_check_functionality(client->adapter,
					I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_err(&client->dev, "i2c smbus byte data not supported\n");
		return -EIO;
	}

	if (!pdata) {
		pdata = bu21013_parse_dt(&client->dev);
		if (IS_ERR(pdata))
			return PTR_ERR(pdata);
	}

	if (!gpio_is_valid(pdata->touch_pin)) {
		dev_err(&client->dev, "invalid touch_pin supplied\n");
		return -EINVAL;
	}

	bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL);
	in_dev = input_allocate_device();
	if (!bu21013_data || !in_dev) {
		dev_err(&client->dev, "device memory alloc failed\n");
		error = -ENOMEM;
		goto err_free_mem;
	}

	bu21013_data->in_dev = in_dev;
	bu21013_data->chip = pdata;
	bu21013_data->client = client;
	bu21013_data->irq = gpio_to_irq(pdata->touch_pin);

	bu21013_data->regulator = regulator_get(&client->dev, "avdd");
	if (IS_ERR(bu21013_data->regulator)) {
		dev_err(&client->dev, "regulator_get failed\n");
		error = PTR_ERR(bu21013_data->regulator);
		goto err_free_mem;
	}

	error = regulator_enable(bu21013_data->regulator);
	if (error < 0) {
		dev_err(&client->dev, "regulator enable failed\n");
		goto err_put_regulator;
	}

	bu21013_data->touch_stopped = false;
	init_waitqueue_head(&bu21013_data->wait);

	/* configure the gpio pins */
	error = gpio_request_one(pdata->cs_pin, GPIOF_OUT_INIT_HIGH,
				 "touchp_reset");
	if (error < 0) {
		dev_err(&client->dev, "Unable to request gpio reset_pin\n");
		goto err_disable_regulator;
	}

	/* configure the touch panel controller */
	error = bu21013_init_chip(bu21013_data);
	if (error) {
		dev_err(&client->dev, "error in bu21013 config\n");
		goto err_cs_disable;
	}

	/* register the device to input subsystem */
	in_dev->name = DRIVER_TP;
	in_dev->id.bustype = BUS_I2C;
	in_dev->dev.parent = &client->dev;

	__set_bit(EV_SYN, in_dev->evbit);
	__set_bit(EV_KEY, in_dev->evbit);
	__set_bit(EV_ABS, in_dev->evbit);

	input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0,
						pdata->touch_x_max, 0, 0);
	input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0,
						pdata->touch_y_max, 0, 0);
	input_set_drvdata(in_dev, bu21013_data);

	error = request_threaded_irq(bu21013_data->irq, NULL, bu21013_gpio_irq,
				     IRQF_TRIGGER_FALLING | IRQF_SHARED |
					IRQF_ONESHOT,
				     DRIVER_TP, bu21013_data);
	if (error) {
		dev_err(&client->dev, "request irq %d failed\n",
			bu21013_data->irq);
		goto err_cs_disable;
	}

	error = input_register_device(in_dev);
	if (error) {
		dev_err(&client->dev, "failed to register input device\n");
		goto err_free_irq;
	}

	device_init_wakeup(&client->dev, pdata->wakeup);
	i2c_set_clientdata(client, bu21013_data);

	return 0;

err_free_irq:
	bu21013_free_irq(bu21013_data);
err_cs_disable:
	bu21013_cs_disable(bu21013_data);
err_disable_regulator:
	regulator_disable(bu21013_data->regulator);
err_put_regulator:
	regulator_put(bu21013_data->regulator);
err_free_mem:
	input_free_device(in_dev);
	kfree(bu21013_data);

	return error;
}