Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c15e38ce authored by Chun Zhang's avatar Chun Zhang Committed by Jing Lin
Browse files

input: bu21149: add pinctrl and regulator support



The bu21150 touch AFE driver does not have pinctrl and regulator to
access GPIOs and do power management. Therefore, add such change to
keep the feasibility.

Change-Id: Iab145096162e83d51aef75f61f3364a0298a3b47
Signed-off-by: default avatarChun Zhang <chunz@codeaurora.org>
parent 242629a2
Loading
Loading
Loading
Loading
+31 −5
Original line number Diff line number Diff line
@@ -6,12 +6,29 @@ Required properties:
 - reg					: SPI address of the device
 - interrupt-parent		: parent of interrupt
 - interrupts			: interrupt of touch AFE
 - spi-max-frequency	: communication speed of the SPI
 - irq-gpio 			: irq gpio
 - rst-gpio				: reset gpio
 - power-supply			: type of power sequence
							Please use when adjusting the power sequence
 - vdd_ana-supply		: analog power supply for AFE panel
 - vdd_dig-supply		: digital power supply for AFE panel

Optional properties:
- pinctrl-names		: This should be defined if a target uses pinctrl framework.
			See "pinctrl" in Documentation/devicetree/bindings/pinctrl/msm-				       pinctrl.txt. It should specify the names of the configs that
			pinctrl can install in driver. Following are the pinctrl
			configs that can be installed:
			"pmx_ts_active" : Active configuration of pins, this should specify
					active config defined in pin groups of interrupt
					and reset gpio.
			"pmx_ts_suspend" : Disabled configuration of pins, this should
					specify sleep config defined in pin groups of
					interrupt and reset gpio.
			"pmx_ts_release" : Release configuration of pins, this should specify
					release config defined in pin groups of interrupt
					and reset gpio.
			"afe_pwr_active" : Active configuration of AFE power pin.
			"afe_pwr_suspend" : Disabled configuration of AFE power pin.
			"disp_vsn_active" : Active configuration of display VSN pin.
			"disp_vsn_suspend" : Disable configuration of display VSN pin.

Example:

@@ -21,10 +38,19 @@ Example:
			reg = <0>;
			interrupt-parent = <&msmgpio>;
			interrupts = <61 0>;
			spi-max-frequency = <9600000>;
			irq-gpio = <&msmgpio 61 0>;
			rst-gpio = <&msmgpio 60 0>;
			power-supply = "apq8074-dragonboard";
			vdd_ana-supply = <&pm8916_l17>;
			vdd_dig-supply = <&pm8916_l6>;
			pinctrl-names = "pmx_ts_active","pmx_ts_suspend",
					"afe_pwr_active", "afe_pwr_suspend",
					"disp_vsn_active", "disp_vsn_suspend";
			pinctrl-0 = <&ts_int_active &ts_reset_active>;
			pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
			pinctrl-2 = <&afe_pwr_active>;
			pinctrl-3 = <&afe_pwr_suspend>;
			pinctrl-4 = <&disp_vsn_active>;
			pinctrl-5 = <&disp_vsn_suspend>;
		};
	};
+406 −136
Original line number Diff line number Diff line
@@ -42,9 +42,10 @@
#define GPIO_HIGH (1)
#define WAITQ_WAIT   (0)
#define WAITQ_WAKEUP (1)
/* #define CHECK_SAME_FRAME */
#define APQ8074_DRAGONBOARD (0x01)
#define MSM8974_FLUID       (0x02)
#define BU21150_MIN_VOLTAGE_UV	2700000
#define BU21150_MAX_VOLTAGE_UV	3300000
#define BU21150_VDD_DIG_VOLTAGE_UV	1800000
#define BU21150_MAX_OPS_LOAD_UA	150000

/* struct */
struct bu21150_data {
@@ -52,6 +53,13 @@ struct bu21150_data {
	struct spi_device *client;
	struct workqueue_struct *workq;
	struct work_struct work;
	struct pinctrl *ts_pinctrl;
	struct pinctrl_state *gpio_state_active;
	struct pinctrl_state *gpio_state_suspend;
	struct pinctrl_state *afe_pwr_state_active;
	struct pinctrl_state *afe_pwr_state_suspend;
	struct pinctrl_state *disp_vsn_state_active;
	struct pinctrl_state *disp_vsn_state_suspend;
	/* frame */
	struct bu21150_ioctl_get_frame_data req_get;
	u8 frame[MAX_FRAME_SIZE];
@@ -68,10 +76,12 @@ struct bu21150_data {
	u8 spi_buf[MAX_FRAME_SIZE];
	/* power */
	struct regulator *vcc_ana;
	struct regulator *vcc_dig;
	/* dtsi */
	int irq_gpio;
	int rst_gpio;
	int power_supply;
	int afe_pwr_gpio;
	int disp_vsn_gpio;
};

struct ser_req {
@@ -80,9 +90,6 @@ struct ser_req {
	u16 sample ____cacheline_aligned;
};

int g_afe_display_state;  /* 0:off, 1:on */
int g_afe_skip_frame_cnt;

/* static function declaration */
static int bu21150_probe(struct spi_device *client);
static int bu21150_remove(struct spi_device *client);
@@ -169,150 +176,420 @@ static int reg_set_optimum_mode_check(struct regulator *reg, int load_ua)
		regulator_set_optimum_mode(reg, load_ua) : 0;
}

static int bu21150_probe(struct spi_device *client)
static int bu21150_pinctrl_init(struct bu21150_data *data)
{
	struct bu21150_data *ts;
	int error;
	int rc;

	ts = kzalloc(sizeof(struct bu21150_data), GFP_KERNEL);
	if (!ts) {
		dev_err(&client->dev, "Out of memory\n");
		return -ENOMEM;
	data->ts_pinctrl = devm_pinctrl_get(&(data->client->dev));
	if (IS_ERR_OR_NULL(data->ts_pinctrl)) {
		dev_err(&data->client->dev,
			"Target does not use pinctrl\n");
		rc = PTR_ERR(data->ts_pinctrl);
		goto error;
	}

	/* parse dtsi */
	if (!parse_dtsi(&client->dev, ts)) {
		dev_err(&client->dev, "Invalid dtsi\n");
		error = -EINVAL;
		goto err1;
	data->gpio_state_active
		= pinctrl_lookup_state(data->ts_pinctrl, "pmx_ts_active");
	if (IS_ERR_OR_NULL(data->gpio_state_active)) {
		dev_dbg(&data->client->dev,
			"Can not get ts default pinstate\n");
		rc = PTR_ERR(data->gpio_state_active);
		goto error;
	}

	/* Panel and AFE Power on sequence */
	if (ts->power_supply == APQ8074_DRAGONBOARD) {
		rc = gpio_request(1, "GPIO1");
		if (rc)
			pr_err("%s: gpio_request(%d) failed\n",
				__func__, 1);
		gpio_direction_output(1, 1);
		gpio_set_value(1, 1);
	data->gpio_state_suspend
		= pinctrl_lookup_state(data->ts_pinctrl, "pmx_ts_suspend");
	if (IS_ERR_OR_NULL(data->gpio_state_suspend)) {
		dev_dbg(&data->client->dev,
			"Can not get ts sleep pinstate\n");
		rc = PTR_ERR(data->gpio_state_suspend);
		goto error;
	}

	data->afe_pwr_state_active
		= pinctrl_lookup_state(data->ts_pinctrl, "afe_pwr_active");
	if (IS_ERR_OR_NULL(data->afe_pwr_state_active)) {
		dev_err(&data->client->dev,
			"Can not get pwr default pinstate\n");
		rc = PTR_ERR(data->afe_pwr_state_active);
		goto error;
	}

	data->afe_pwr_state_suspend
		= pinctrl_lookup_state(data->ts_pinctrl, "afe_pwr_suspend");
	if (IS_ERR_OR_NULL(data->afe_pwr_state_suspend)) {
		dev_err(&data->client->dev,
			"Can not get pwr sleep pinstate\n");
		rc = PTR_ERR(data->afe_pwr_state_suspend);
		goto error;
	}

	data->disp_vsn_state_active
		= pinctrl_lookup_state(data->ts_pinctrl, "disp_vsn_active");
	if (IS_ERR_OR_NULL(data->disp_vsn_state_active)) {
		dev_err(&data->client->dev,
			"Can not get disp_vsn default pinstate\n");
		rc = PTR_ERR(data->disp_vsn_state_active);
		goto error;
	}

	data->disp_vsn_state_suspend
		= pinctrl_lookup_state(data->ts_pinctrl, "disp_vsn_suspend");
	if (IS_ERR_OR_NULL(data->disp_vsn_state_suspend)) {
		dev_err(&data->client->dev,
			"Can not get disp_vsn sleep pinstate\n");
		rc = PTR_ERR(data->disp_vsn_state_suspend);
		goto error;
	}

	return 0;

error:
	data->ts_pinctrl = NULL;
	return rc;
}

static int bu21150_pinctrl_select(struct bu21150_data *data, bool on)
{
	struct pinctrl_state *pins_state;
	int ret = 0;

	pins_state = on ? data->gpio_state_active : data->gpio_state_suspend;
	if (!IS_ERR_OR_NULL(pins_state)) {
		ret = pinctrl_select_state(data->ts_pinctrl, pins_state);
		if (ret) {
			dev_err(&data->client->dev,
				"can not set %s pins\n",
				on ? "pmx_ts_active" : "pmx_ts_suspend");
			return ret;
		}
	} else {
		dev_err(&data->client->dev,
			"not a valid '%s' pinstate\n",
				on ? "pmx_ts_active" : "pmx_ts_suspend");
		return -EINVAL;
	}

	return ret;
}

static int bu21150_pinctrl_enable(struct bu21150_data *ts, bool on)
{
	int rc = 0;

	if (!on)
		goto pinctrl_suspend;

	rc = pinctrl_select_state(ts->ts_pinctrl,
					ts->afe_pwr_state_active);
	if (rc) {
		dev_err(&ts->client->dev, "can not set afe pwr pins\n");
		return -EINVAL;
	}
	usleep(1000);
		rc = gpio_request(92, "GPIO2");
		if (rc)
			pr_err("%s: gpio_request(%d) failed\n",
				__func__, 92);
		gpio_direction_output(92, 1);
		gpio_set_value(92, 1);

	rc = pinctrl_select_state(ts->ts_pinctrl,
				ts->disp_vsn_state_active);
	if (rc) {
		dev_err(&ts->client->dev,
				"can not set disp vsn pins\n");
		goto err_disp_vsn_pinctrl_enable;
	}
	usleep(1000);

	rc = bu21150_pinctrl_select(ts, true);
	if (rc < 0)
		goto err_ts_pinctrl_enable;

	return 0;

pinctrl_suspend:
	bu21150_pinctrl_select(ts, false);
err_ts_pinctrl_enable:
	pinctrl_select_state(ts->ts_pinctrl, ts->disp_vsn_state_suspend);
err_disp_vsn_pinctrl_enable:
	pinctrl_select_state(ts->ts_pinctrl, ts->afe_pwr_state_suspend);

	return rc;
}

static int bu21150_gpio_enable(struct bu21150_data *ts, bool on)
{
	int rc = 0;

	if (!on)
		goto gpio_disable;

	/* Panel and AFE Power on sequence */
	rc = gpio_request(ts->afe_pwr_gpio, "afe_pwr");
	if (rc) {
		pr_err("%s: afe power gpio request failed\n", __func__);
		return -EINVAL;
	}
	gpio_direction_output(ts->afe_pwr_gpio, 1);
	gpio_set_value(ts->afe_pwr_gpio, 1);
	usleep(1000);
		rc = gpio_request(0, "GPIO3");
		if (rc)
			pr_err("%s: gpio_request(%d) failed\n",
				__func__, 0);
		gpio_direction_output(0, 1);
		gpio_set_value(0, 1);

	rc = gpio_request(ts->disp_vsn_gpio, "disp_vsn");
	if (rc) {
		pr_err("%s: disp_vsn gpio request failed\n", __func__);
		goto err_disp_vsn_gpio_enable;
	}
	gpio_direction_output(ts->disp_vsn_gpio, 1);
	gpio_set_value(ts->disp_vsn_gpio, 1);
	usleep(1000);
	} else if (ts->power_supply == MSM8974_FLUID) {
		ts->vcc_ana = regulator_get(&client->dev, "vdd_ana");
		if (IS_ERR(ts->vcc_ana)) {
			rc = PTR_ERR(ts->vcc_ana);
			dev_err(&client->dev,
				"Regulator get failed vcc_ana rc=%d\n", rc);
			error = -EINVAL;
			goto err1;

	rc = gpio_request(ts->irq_gpio, "bu21150_ts_int");
	if (rc) {
		pr_err("%s: IRQ gpio_request failed\n", __func__);
		goto err_irq_gpio_enable;
	}
	gpio_direction_input(ts->irq_gpio);

	/* set reset */
	rc = gpio_request(ts->rst_gpio, "bu21150_ts_reset");
	if (rc) {
		pr_err("%s: reset gpio_request failed\n", __func__);
		goto err_rst_gpio_enable;
	}

	gpio_direction_output(ts->rst_gpio, GPIO_LOW);

	return 0;

gpio_disable:
	gpio_free(ts->rst_gpio);
err_rst_gpio_enable:
	gpio_free(ts->irq_gpio);
err_irq_gpio_enable:
	gpio_free(ts->disp_vsn_gpio);
err_disp_vsn_gpio_enable:
	gpio_free(ts->afe_pwr_gpio);

	return rc;
}

static int bu21150_pin_enable(struct bu21150_data *ts, bool on)
{
	int rc = 0;

	if (!on)
		goto pin_disable;

	if (ts->ts_pinctrl)
		rc = bu21150_pinctrl_enable(ts, true);
	else
		rc = bu21150_gpio_enable(ts, true);

	return rc;

pin_disable:
	if (ts->ts_pinctrl)
		bu21150_pinctrl_enable(ts, false);
	else
		bu21150_gpio_enable(ts, false);

	return rc;
}

static int bu21150_power_enable(struct bu21150_data *ts, bool on)
{
	int rc = 0;

	if (!on)
		goto power_disable;

	if (regulator_count_voltages(ts->vcc_ana) > 0) {
			rc = regulator_set_voltage(ts->vcc_ana, 2700000,
								3300000);
		rc = regulator_set_voltage(ts->vcc_ana,
			BU21150_MIN_VOLTAGE_UV, BU21150_MAX_VOLTAGE_UV);
		if (rc) {
				dev_err(&client->dev,
					"regulator set_vtg failed rc=%d\n", rc);
				error = -EINVAL;
				goto error_set_vtg_vcc_ana;
			dev_err(&ts->client->dev,
				"regulator vcc_ana set_vtg failed rc=%d\n", rc);
			return rc;
		}
	}
		rc = reg_set_optimum_mode_check(ts->vcc_ana, 150000);

	rc = reg_set_optimum_mode_check(ts->vcc_ana,
						BU21150_MAX_OPS_LOAD_UA);
	if (rc < 0) {
			dev_err(&client->dev,
		dev_err(&ts->client->dev,
			"Regulator vcc_ana set_opt failed rc=%d\n", rc);
			error = -EINVAL;
			goto error_set_vtg_vcc_ana;
		goto err_set_vcc_ana_opt_mode;
	}

	rc = regulator_enable(ts->vcc_ana);
	if (rc) {
			dev_err(&client->dev,
		dev_err(&ts->client->dev,
			"Regulator vcc_ana enable failed rc=%d\n", rc);
			error = -EINVAL;
			goto error_reg_en_vcc_ana;
		goto err_enable_vcc_ana;
	}

	if (regulator_count_voltages(ts->vcc_dig) > 0) {
		rc = regulator_set_voltage(ts->vcc_dig,
						BU21150_VDD_DIG_VOLTAGE_UV,
						BU21150_VDD_DIG_VOLTAGE_UV);
		if (rc) {
			dev_err(&ts->client->dev,
				"regulator vcc_dig set_vtg failed rc=%d\n", rc);
			goto err_set_vcc_dig_voltage;
		}
	}

	rc = gpio_request(ts->irq_gpio, "bu21150_ts_int");
	if (rc)
		pr_err("%s: gpio_request(%d) failed\n", __func__, ts->irq_gpio);
	gpio_direction_input(ts->irq_gpio);
	rc = reg_set_optimum_mode_check(ts->vcc_dig,
						BU21150_MAX_OPS_LOAD_UA);
	if (rc < 0) {
		dev_err(&ts->client->dev,
			"Regulator vcc_dig set_opt failed rc=%d\n", rc);
		goto err_set_vcc_dig_opt_mode;
	}

	/* set reset */
	rc = gpio_request(ts->rst_gpio, "bu21150_ts_reset");
	if (rc)
		pr_err("%s: gpio_request(%d) failed\n", __func__, ts->rst_gpio);
	gpio_direction_output(ts->rst_gpio, GPIO_LOW);
	rc = regulator_enable(ts->vcc_dig);
	if (rc) {
		dev_err(&ts->client->dev,
			"Regulator vcc_dig enable failed rc=%d\n", rc);
		goto err_enable_vcc_dig;
	}

	mutex_init(&ts->mutex_frame);
	init_waitqueue_head(&(ts->frame_waitq));
	return 0;

power_disable:
	regulator_disable(ts->vcc_dig);
err_enable_vcc_dig:
	reg_set_optimum_mode_check(ts->vcc_dig, 0);
err_set_vcc_dig_opt_mode:
	if (regulator_count_voltages(ts->vcc_dig) > 0)
		regulator_set_voltage(ts->vcc_dig, 0,
					BU21150_VDD_DIG_VOLTAGE_UV);
err_set_vcc_dig_voltage:
	regulator_disable(ts->vcc_ana);
err_enable_vcc_ana:
	reg_set_optimum_mode_check(ts->vcc_ana, 0);
err_set_vcc_ana_opt_mode:
	if (regulator_count_voltages(ts->vcc_ana) > 0)
		regulator_set_voltage(ts->vcc_ana, 0, BU21150_MAX_VOLTAGE_UV);

	return rc;
}

static int bu21150_regulator_config(struct bu21150_data *ts, bool enable)
{
	int rc = 0;

	if (!enable)
		goto regulator_release;

	ts->vcc_ana = regulator_get(&ts->client->dev, "vdd_ana");
	if (IS_ERR_OR_NULL(ts->vcc_ana)) {
		rc = PTR_ERR(ts->vcc_ana);
		dev_err(&ts->client->dev,
			"Regulator get failed vcc_ana rc=%d\n", rc);
		return rc;
	}

	ts->vcc_dig = regulator_get(&ts->client->dev, "vdd_dig");
	if (IS_ERR_OR_NULL(ts->vcc_dig)) {
		rc = PTR_ERR(ts->vcc_dig);
		dev_err(&ts->client->dev,
			"Regulator get failed vcc_dig rc=%d\n", rc);
		goto err_get_vdd_dig;
	}

	return 0;

regulator_release:
	regulator_put(ts->vcc_dig);
err_get_vdd_dig:
	regulator_put(ts->vcc_ana);

	return rc;
}

static int bu21150_probe(struct spi_device *client)
{
	struct bu21150_data *ts;
	int rc;

	ts = kzalloc(sizeof(struct bu21150_data), GFP_KERNEL);
	if (!ts) {
		dev_err(&client->dev, "Out of memory\n");
		return -ENOMEM;
	}

	/* parse dtsi */
	if (!parse_dtsi(&client->dev, ts)) {
		dev_err(&client->dev, "Invalid dtsi\n");
		rc = -EINVAL;
		goto err_parse_dt;
	}

	g_client_bu21150 = client;
	ts->client = client;

	rc = bu21150_pinctrl_init(ts);
	if (rc) {
		dev_err(&client->dev, "Pinctrl init failed\n");
		goto err_parse_dt;
	}

	rc = bu21150_regulator_config(ts, true);
	if (rc) {
		dev_err(&client->dev, "Failed to get power rail\n");
		goto err_regulator_config;
	}

	rc = bu21150_power_enable(ts, true);
	if (rc) {
		dev_err(&client->dev, "Power enablement failed\n");
		goto err_power_enable;
	}

	rc = bu21150_pin_enable(ts, true);
	if (rc) {
		dev_err(&client->dev, "Pin enable failed\n");
		goto err_pin_enable;
	}

	mutex_init(&ts->mutex_frame);
	init_waitqueue_head(&(ts->frame_waitq));

	ts->workq = create_singlethread_workqueue("bu21150_workq");
	if (!ts->workq) {
		dev_err(&client->dev, "Unable to create workq\n");
		error =  -ENOMEM;
		goto err2;
		rc =  -ENOMEM;
		goto err_create_wq;
	}
	INIT_WORK(&ts->work, bu21150_irq_work_func);

	if (!client->irq) {
		dev_err(&client->dev, "Bad irq\n");
		error = -EINVAL;
		goto err3;
	}

	error = request_irq(client->irq, bu21150_irq_handler,
				IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				client->dev.driver->name, ts);
	if (error) {
		dev_err(&client->dev, "Failed to register interrupt\n");
		goto err3;
		rc = -EINVAL;
		goto err_create_wq;
	}
	disable_irq(client->irq);

	error = misc_register(&g_bu21150_misc_device);
	if (error) {
	rc = misc_register(&g_bu21150_misc_device);
	if (rc) {
		dev_err(&client->dev, "Failed to register misc device\n");
		goto err4;
		goto err_register_misc;
	}

	dev_set_drvdata(&client->dev, ts);

	return 0;

err4:
	free_irq(client->irq, ts);
err3:
err_register_misc:
	destroy_workqueue(ts->workq);
err2:
	if (ts->power_supply == MSM8974_FLUID)
		regulator_disable(ts->vcc_ana);
error_reg_en_vcc_ana:
	if (ts->power_supply == MSM8974_FLUID)
		reg_set_optimum_mode_check(ts->vcc_ana, 0);
error_set_vtg_vcc_ana:
	if (ts->power_supply == MSM8974_FLUID)
		regulator_put(ts->vcc_ana);
err1:
err_create_wq:
	bu21150_pin_enable(ts, false);
err_pin_enable:
	bu21150_power_enable(ts, false);
err_power_enable:
	bu21150_regulator_config(ts, false);
err_regulator_config:
	if (ts->ts_pinctrl)
		devm_pinctrl_put(ts->ts_pinctrl);
err_parse_dt:
	kfree(ts);
	return error;
	return rc;
}

static int bu21150_remove(struct spi_device *client)
@@ -320,8 +597,11 @@ static int bu21150_remove(struct spi_device *client)
	struct bu21150_data *ts = spi_get_drvdata(client);

	misc_deregister(&g_bu21150_misc_device);
	bu21150_power_enable(ts, false);
	bu21150_regulator_config(ts, false);
	destroy_workqueue(ts->workq);
	free_irq(client->irq, ts);
	bu21150_pin_enable(ts, false);
	kfree(ts);

	return 0;
@@ -331,6 +611,7 @@ static int bu21150_open(struct inode *inode, struct file *filp)
{
	struct bu21150_data *ts = spi_get_drvdata(g_client_bu21150);
	struct spi_device *client = ts->client;
	int error;

	if (g_io_opened) {
		pr_err("%s: g_io_opened not zero.\n", __func__);
@@ -346,7 +627,14 @@ static int bu21150_open(struct inode *inode, struct file *filp)
		sizeof(struct bu21150_ioctl_get_frame_data));
	memset(&(ts->frame_work_get), 0,
		sizeof(struct bu21150_ioctl_get_frame_data));
	enable_irq(client->irq);

	error = request_irq(client->irq, bu21150_irq_handler,
				IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				client->dev.driver->name, ts);
	if (error) {
		dev_err(&client->dev, "Failed to register interrupt\n");
		return error;
	}

	return 0;
}
@@ -401,7 +689,7 @@ static long bu21150_ioctl(struct file *filp, unsigned int cmd,
		ret = bu21150_ioctl_resume();
		return ret;
	default:
		pr_err("%s: cmd unkown.\n", __func__);
		pr_err("%s: cmd unknown.\n", __func__);
		return -EINVAL;
	}

@@ -467,8 +755,6 @@ static long bu21150_ioctl_reset(unsigned long reset)
	}

	if (reset == BU21150_RESET_HIGH) {
		/* wait display on */
		while (g_afe_display_state == 0) /* 0:off */
		usleep(1000);
	}

@@ -562,6 +848,7 @@ static long bu21150_ioctl_suspend(void)

	bu21150_ioctl_unblock();
	disable_irq(client->irq);
	bu21150_power_enable(ts, false);

	return 0;
}
@@ -572,6 +859,7 @@ static long bu21150_ioctl_resume(void)
	struct spi_device *client = ts->client;

	g_bu21150_ioctl_unblock = 0;
	bu21150_power_enable(ts, true);
	enable_irq(client->irq);

	return 0;
@@ -599,17 +887,11 @@ static void bu21150_irq_work_func(struct work_struct *work)
	ts->frame_work_get = ts->req_get;
	bu21150_read_register(REG_READ_DATA, ts->frame_work_get.size, psbuf);

	if (0 < g_afe_skip_frame_cnt) {
		pr_err("%s: skip frame:cnt=[%d]\n",
			__func__, g_afe_skip_frame_cnt);
		g_afe_skip_frame_cnt--;
	} else {
#ifdef CHECK_SAME_FRAME
	check_same_frame(ts);
#endif
	copy_frame(ts);
	wake_up_frame_waitq(ts);
	}

	enable_irq(client->irq);
}
@@ -638,7 +920,7 @@ static int bu21150_read_register(u32 addr, u16 size, u8 *data)
	req->xfer[0].rx_buf = output;
	req->xfer[0].len = size+SPI_HEADER_SIZE;
	req->xfer[0].cs_change = 0;
	req->xfer[0].bits_per_word = 32;
	req->xfer[0].bits_per_word = 8;
	spi_message_add_tail(&req->xfer[0], &req->msg);
	ret = spi_sync(client, &req->msg);
	if (ret)
@@ -769,25 +1051,13 @@ static void check_same_frame(struct bu21150_data *ts)

static bool parse_dtsi(struct device *dev, struct bu21150_data *ts)
{
	int rc;
	enum of_gpio_flags dummy;
	const char *str;
	struct device_node *np = dev->of_node;

	ts->irq_gpio = of_get_named_gpio_flags(np,
		"irq-gpio", 0, &dummy);
	ts->rst_gpio = of_get_named_gpio_flags(np,
		"rst-gpio", 0, &dummy);
	rc = of_property_read_string(np,
		"power-supply", &str);
	if (rc && (rc != -EINVAL))
		dev_err(dev, "Unable to read power-supply\n");
	if (!strcmp(str, "apq8074-dragonboard"))
		ts->power_supply = APQ8074_DRAGONBOARD;
	else if (!strcmp(str, "msm8974-fluid"))
		ts->power_supply = MSM8974_FLUID;
	else
		return false;

	return true;
}