diff options
Diffstat (limited to 'drivers/input/touchscreen/bu21013_ts.c')
-rw-r--r-- | drivers/input/touchscreen/bu21013_ts.c | 125 |
1 files changed, 99 insertions, 26 deletions
diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c index 5c487d23f11..b9b5ddad665 100644 --- a/drivers/input/touchscreen/bu21013_ts.c +++ b/drivers/input/touchscreen/bu21013_ts.c @@ -14,6 +14,9 @@ #include <linux/slab.h> #include <linux/regulator/consumer.h> #include <linux/module.h> +#include <linux/gpio.h> +#include <linux/of.h> +#include <linux/of_gpio.h> #define PEN_DOWN_INTR 0 #define MAX_FINGERS 2 @@ -148,11 +151,12 @@ struct bu21013_ts_data { struct i2c_client *client; wait_queue_head_t wait; - bool touch_stopped; const struct bu21013_platform_device *chip; struct input_dev *in_dev; - unsigned int intr_pin; struct regulator *regulator; + unsigned int irq; + unsigned int intr_pin; + bool touch_stopped; }; /** @@ -262,7 +266,7 @@ static irqreturn_t bu21013_gpio_irq(int irq, void *device_data) return IRQ_NONE; } - data->intr_pin = data->chip->irq_read_val(); + data->intr_pin = gpio_get_value(data->chip->touch_pin); if (data->intr_pin == PEN_DOWN_INTR) wait_event_timeout(data->wait, data->touch_stopped, msecs_to_jiffies(2)); @@ -418,8 +422,70 @@ static void bu21013_free_irq(struct bu21013_ts_data *bu21013_data) { bu21013_data->touch_stopped = true; wake_up(&bu21013_data->wait); - free_irq(bu21013_data->chip->irq, bu21013_data); + free_irq(bu21013_data->irq, bu21013_data); +} + +/** + * bu21013_cs_disable() - deconfigures the touch panel controller + * @bu21013_data: device structure pointer + * + * This function is used to deconfigure the chip selection + * for touch panel controller. + */ +static void bu21013_cs_disable(struct bu21013_ts_data *bu21013_data) +{ + int error; + + error = gpio_direction_output(bu21013_data->chip->cs_pin, 0); + if (error < 0) + dev_warn(&bu21013_data->client->dev, + "%s: gpio direction failed, error: %d\n", + __func__, error); + else + gpio_set_value(bu21013_data->chip->cs_pin, 0); + + gpio_free(bu21013_data->chip->cs_pin); +} + +#ifdef CONFIG_OF +static const struct bu21013_platform_device * +bu21013_parse_dt(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct bu21013_platform_device *pdata; + + if (!np) { + dev_err(dev, "no device tree or platform data\n"); + return ERR_PTR(-EINVAL); + } + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + pdata->y_flip = pdata->x_flip = false; + + pdata->x_flip = of_property_read_bool(np, "rohm,flip-x"); + pdata->y_flip = of_property_read_bool(np, "rohm,flip-y"); + + of_property_read_u32(np, "rohm,touch-max-x", &pdata->touch_x_max); + of_property_read_u32(np, "rohm,touch-max-y", &pdata->touch_y_max); + + pdata->touch_pin = of_get_named_gpio(np, "touch-gpio", 0); + pdata->cs_pin = of_get_named_gpio(np, "reset-gpio", 0); + + pdata->ext_clk = false; + + return pdata; } +#else +static inline const struct bu21013_platform_device * +bu21013_parse_dt(struct device *dev) +{ + dev_err(dev, "no platform data available\n"); + return ERR_PTR(-EINVAL); +} +#endif /** * bu21013_probe() - initializes the i2c-client touchscreen driver @@ -429,13 +495,13 @@ static void bu21013_free_irq(struct bu21013_ts_data *bu21013_data) * 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) +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; - const struct bu21013_platform_device *pdata = - client->dev.platform_data; int error; if (!i2c_check_functionality(client->adapter, @@ -445,7 +511,13 @@ static int __devinit bu21013_probe(struct i2c_client *client, } if (!pdata) { - dev_err(&client->dev, "platform data not defined\n"); + 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; } @@ -460,8 +532,9 @@ static int __devinit bu21013_probe(struct i2c_client *client, 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, "V-TOUCH"); + 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); @@ -478,12 +551,11 @@ static int __devinit bu21013_probe(struct i2c_client *client, init_waitqueue_head(&bu21013_data->wait); /* configure the gpio pins */ - 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 = 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 */ @@ -508,12 +580,13 @@ static int __devinit bu21013_probe(struct i2c_client *client, pdata->touch_y_max, 0, 0); input_set_drvdata(in_dev, bu21013_data); - error = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq, + 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", pdata->irq); + dev_err(&client->dev, "request irq %d failed\n", + bu21013_data->irq); goto err_cs_disable; } @@ -531,7 +604,7 @@ static int __devinit bu21013_probe(struct i2c_client *client, err_free_irq: bu21013_free_irq(bu21013_data); err_cs_disable: - pdata->cs_dis(pdata->cs_pin); + bu21013_cs_disable(bu21013_data); err_disable_regulator: regulator_disable(bu21013_data->regulator); err_put_regulator: @@ -549,13 +622,13 @@ err_free_mem: * This function uses to remove the i2c-client * touchscreen driver and returns integer. */ -static int __devexit bu21013_remove(struct i2c_client *client) +static int bu21013_remove(struct i2c_client *client) { struct bu21013_ts_data *bu21013_data = i2c_get_clientdata(client); bu21013_free_irq(bu21013_data); - bu21013_data->chip->cs_dis(bu21013_data->chip->cs_pin); + bu21013_cs_disable(bu21013_data); input_unregister_device(bu21013_data->in_dev); @@ -584,9 +657,9 @@ static int bu21013_suspend(struct device *dev) bu21013_data->touch_stopped = true; if (device_may_wakeup(&client->dev)) - enable_irq_wake(bu21013_data->chip->irq); + enable_irq_wake(bu21013_data->irq); else - disable_irq(bu21013_data->chip->irq); + disable_irq(bu21013_data->irq); regulator_disable(bu21013_data->regulator); @@ -621,9 +694,9 @@ static int bu21013_resume(struct device *dev) bu21013_data->touch_stopped = false; if (device_may_wakeup(&client->dev)) - disable_irq_wake(bu21013_data->chip->irq); + disable_irq_wake(bu21013_data->irq); else - enable_irq(bu21013_data->chip->irq); + enable_irq(bu21013_data->irq); return 0; } @@ -649,7 +722,7 @@ static struct i2c_driver bu21013_driver = { #endif }, .probe = bu21013_probe, - .remove = __devexit_p(bu21013_remove), + .remove = bu21013_remove, .id_table = bu21013_id, }; |