···11+* Texas Instruments tsc2007 touchscreen controller22+33+Required properties:44+- compatible: must be "ti,tsc2007".55+- reg: I2C address of the chip.66+- ti,x-plate-ohms: X-plate resistance in ohms.77+88+Optional properties:99+- gpios: the interrupt gpio the chip is connected to (trough the penirq pin).1010+ The penirq pin goes to low when the panel is touched.1111+ (see GPIO binding[1] for more details).1212+- interrupt-parent: the phandle for the gpio controller1313+ (see interrupt binding[0]).1414+- interrupts: (gpio) interrupt to which the chip is connected1515+ (see interrupt binding[0]).1616+- ti,max-rt: maximum pressure.1717+- ti,fuzzx: specifies the absolute input fuzz x value.1818+ If set, it will permit noise in the data up to +- the value given to the fuzz1919+ parameter, that is used to filter noise from the event stream.2020+- ti,fuzzy: specifies the absolute input fuzz y value.2121+- ti,fuzzz: specifies the absolute input fuzz z value.2222+- ti,poll-period: how much time to wait (in milliseconds) before reading again the2323+ values from the tsc2007.2424+2525+[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt2626+[1]: Documentation/devicetree/bindings/gpio/gpio.txt2727+2828+Example:2929+ &i2c1 {3030+ /* ... */3131+ tsc2007@49 {3232+ compatible = "ti,tsc2007";3333+ reg = <0x49>;3434+ interrupt-parent = <&gpio4>;3535+ interrupts = <0x0 0x8>;3636+ gpios = <&gpio4 0 0>;3737+ ti,x-plate-ohms = <180>;3838+ };3939+4040+ /* ... */4141+ };
+1-1
arch/arm/mach-imx/mach-cpuimx35.c
···5353};54545555#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2)5656-static int tsc2007_get_pendown_state(void)5656+static int tsc2007_get_pendown_state(struct device *dev)5757{5858 return !gpio_get_value(TSC2007_IRQGPIO);5959}
+1-1
arch/arm/mach-imx/mach-cpuimx51sd.c
···121121 .flags = IMXUART_HAVE_RTSCTS,122122};123123124124-static int tsc2007_get_pendown_state(void)124124+static int tsc2007_get_pendown_state(struct device *dev)125125{126126 if (mx51_revision() < IMX_CHIP_REVISION_3_0)127127 return !gpio_get_value(TSC2007_IRQGPIO_REV2);
+1-1
arch/sh/boards/mach-ecovec24/setup.c
···501501/* TouchScreen */502502#define IRQ0 evt2irq(0x600)503503504504-static int ts_get_pendown_state(void)504504+static int ts_get_pendown_state(struct device *dev)505505{506506 int val = 0;507507 gpio_free(GPIO_FN_INTC_IRQ0);
+133-40
drivers/input/touchscreen/tsc2007.c
···2626#include <linux/interrupt.h>2727#include <linux/i2c.h>2828#include <linux/i2c/tsc2007.h>2929+#include <linux/of_device.h>3030+#include <linux/of.h>3131+#include <linux/of_gpio.h>29323033#define TSC2007_MEASURE_TEMP0 (0x0 << 4)3134#define TSC2007_MEASURE_AUX (0x2 << 4)···7774 u16 max_rt;7875 unsigned long poll_delay;7976 unsigned long poll_period;7777+ int fuzzx;7878+ int fuzzy;7979+ int fuzzz;80808181+ unsigned gpio;8182 int irq;82838384 wait_queue_head_t wait;8485 bool stopped;85868686- int (*get_pendown_state)(void);8787+ int (*get_pendown_state)(struct device *);8788 void (*clear_penirq)(void);8889};8990···168161 if (!ts->get_pendown_state)169162 return true;170163171171- return ts->get_pendown_state();164164+ return ts->get_pendown_state(&ts->client->dev);172165}173166174167static irqreturn_t tsc2007_soft_irq(int irq, void *handle)···185178186179 rt = tsc2007_calculate_pressure(ts, &tc);187180188188- if (rt == 0 && !ts->get_pendown_state) {181181+ if (!rt && !ts->get_pendown_state) {189182 /*190183 * If pressure reported is 0 and we don't have191184 * callback to check pendown state, we have to···235228{236229 struct tsc2007 *ts = handle;237230238238- if (!ts->get_pendown_state || likely(ts->get_pendown_state()))231231+ if (tsc2007_is_pen_down(ts))239232 return IRQ_WAKE_THREAD;240233241234 if (ts->clear_penirq)···280273 tsc2007_stop(ts);281274}282275283283-static int tsc2007_probe(struct i2c_client *client,284284- const struct i2c_device_id *id)276276+#ifdef CONFIG_OF277277+static int tsc2007_get_pendown_state_gpio(struct device *dev)285278{286286- struct tsc2007 *ts;287287- struct tsc2007_platform_data *pdata = client->dev.platform_data;288288- struct input_dev *input_dev;289289- int err;279279+ struct i2c_client *client = to_i2c_client(dev);280280+ struct tsc2007 *ts = i2c_get_clientdata(client);290281291291- if (!pdata) {292292- dev_err(&client->dev, "platform data is required!\n");282282+ return !gpio_get_value(ts->gpio);283283+}284284+285285+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)286286+{287287+ struct device_node *np = client->dev.of_node;288288+ u32 val32;289289+ u64 val64;290290+291291+ if (!np) {292292+ dev_err(&client->dev, "missing device tree data\n");293293 return -EINVAL;294294 }295295296296- if (!i2c_check_functionality(client->adapter,297297- I2C_FUNC_SMBUS_READ_WORD_DATA))298298- return -EIO;296296+ if (!of_property_read_u32(np, "ti,max-rt", &val32))297297+ ts->max_rt = val32;298298+ else299299+ ts->max_rt = MAX_12BIT;299300300300- ts = kzalloc(sizeof(struct tsc2007), GFP_KERNEL);301301- input_dev = input_allocate_device();302302- if (!ts || !input_dev) {303303- err = -ENOMEM;304304- goto err_free_mem;301301+ if (!of_property_read_u32(np, "ti,fuzzx", &val32))302302+ ts->fuzzx = val32;303303+304304+ if (!of_property_read_u32(np, "ti,fuzzy", &val32))305305+ ts->fuzzy = val32;306306+307307+ if (!of_property_read_u32(np, "ti,fuzzz", &val32))308308+ ts->fuzzz = val32;309309+310310+ if (!of_property_read_u64(np, "ti,poll-period", &val64))311311+ ts->poll_period = val64;312312+ else313313+ ts->poll_period = 1;314314+315315+ if (!of_property_read_u32(np, "ti,x-plate-ohms", &val32)) {316316+ ts->x_plate_ohms = val32;317317+ } else {318318+ dev_err(&client->dev, "missing ti,x-plate-ohms devicetree property.");319319+ return -EINVAL;305320 }306321307307- ts->client = client;308308- ts->irq = client->irq;309309- ts->input = input_dev;310310- init_waitqueue_head(&ts->wait);322322+ ts->gpio = of_get_gpio(np, 0);323323+ if (gpio_is_valid(ts->gpio))324324+ ts->get_pendown_state = tsc2007_get_pendown_state_gpio;325325+ else326326+ dev_warn(&client->dev,327327+ "GPIO not specified in DT (of_get_gpio returned %d)\n",328328+ ts->gpio);311329330330+ return 0;331331+}332332+#else333333+static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)334334+{335335+ dev_err(&client->dev, "platform data is required!\n");336336+ return -EINVAL;337337+}338338+#endif339339+340340+static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,341341+ const struct tsc2007_platform_data *pdata,342342+ const struct i2c_device_id *id)343343+{312344 ts->model = pdata->model;313345 ts->x_plate_ohms = pdata->x_plate_ohms;314346 ts->max_rt = pdata->max_rt ? : MAX_12BIT;···355309 ts->poll_period = pdata->poll_period ? : 1;356310 ts->get_pendown_state = pdata->get_pendown_state;357311 ts->clear_penirq = pdata->clear_penirq;312312+ ts->fuzzx = pdata->fuzzx;313313+ ts->fuzzy = pdata->fuzzy;314314+ ts->fuzzz = pdata->fuzzz;358315359316 if (pdata->x_plate_ohms == 0) {360317 dev_err(&client->dev, "x_plate_ohms is not set up in platform data");361361- err = -EINVAL;362362- goto err_free_mem;318318+ return -EINVAL;363319 }320320+321321+ return 0;322322+}323323+324324+static int tsc2007_probe(struct i2c_client *client,325325+ const struct i2c_device_id *id)326326+{327327+ const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);328328+ struct tsc2007 *ts;329329+ struct input_dev *input_dev;330330+ int err;331331+332332+ if (!i2c_check_functionality(client->adapter,333333+ I2C_FUNC_SMBUS_READ_WORD_DATA))334334+ return -EIO;335335+336336+ ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL);337337+ if (!ts)338338+ return -ENOMEM;339339+340340+ if (pdata)341341+ err = tsc2007_probe_pdev(client, ts, pdata, id);342342+ else343343+ err = tsc2007_probe_dt(client, ts);344344+ if (err)345345+ return err;346346+347347+ input_dev = input_allocate_device();348348+ if (!input_dev) {349349+ err = -ENOMEM;350350+ goto err_free_input;351351+ };352352+353353+ i2c_set_clientdata(client, ts);354354+355355+ ts->client = client;356356+ ts->irq = client->irq;357357+ ts->input = input_dev;358358+ init_waitqueue_head(&ts->wait);364359365360 snprintf(ts->phys, sizeof(ts->phys),366361 "%s/input0", dev_name(&client->dev));···418331 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);419332 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);420333421421- input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0);422422- input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0);334334+ input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0);335335+ input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);423336 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,424424- pdata->fuzzz, 0);337337+ ts->fuzzz, 0);425338426426- if (pdata->init_platform_hw)339339+ if (pdata && pdata->init_platform_hw)427340 pdata->init_platform_hw();428341429342 err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq,430343 IRQF_ONESHOT, client->dev.driver->name, ts);431344 if (err < 0) {432345 dev_err(&client->dev, "irq %d busy?\n", ts->irq);433433- goto err_free_mem;346346+ goto err_free_input;434347 }435348436349 tsc2007_stop(ts);···439352 if (err)440353 goto err_free_irq;441354442442- i2c_set_clientdata(client, ts);443443-444355 return 0;445356446357 err_free_irq:447358 free_irq(ts->irq, ts);448448- if (pdata->exit_platform_hw)359359+ if (pdata && pdata->exit_platform_hw)449360 pdata->exit_platform_hw();450450- err_free_mem:361361+ err_free_input:451362 input_free_device(input_dev);452452- kfree(ts);453363 return err;454364}455365456366static int tsc2007_remove(struct i2c_client *client)457367{458458- struct tsc2007 *ts = i2c_get_clientdata(client);459459- struct tsc2007_platform_data *pdata = client->dev.platform_data;368368+ const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);369369+ struct tsc2007 *ts = i2c_get_clientdata(client);460370461371 free_irq(ts->irq, ts);462372463463- if (pdata->exit_platform_hw)373373+ if (pdata && pdata->exit_platform_hw)464374 pdata->exit_platform_hw();465375466376 input_unregister_device(ts->input);···473389474390MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);475391392392+#ifdef CONFIG_OF393393+static const struct of_device_id tsc2007_of_match[] = {394394+ { .compatible = "ti,tsc2007" },395395+ { /* sentinel */ }396396+};397397+MODULE_DEVICE_TABLE(of, tsc2007_of_match);398398+#endif399399+476400static struct i2c_driver tsc2007_driver = {477401 .driver = {478402 .owner = THIS_MODULE,479479- .name = "tsc2007"403403+ .name = "tsc2007",404404+ .of_match_table = of_match_ptr(tsc2007_of_match),480405 },481406 .id_table = tsc2007_idtable,482407 .probe = tsc2007_probe,
+3-3
include/linux/i2c/tsc2007.h
···1414 int fuzzy;1515 int fuzzz;16161717- int (*get_pendown_state)(void);1818- void (*clear_penirq)(void); /* If needed, clear 2nd level1919- interrupt source */1717+ int (*get_pendown_state)(struct device *);1818+ /* If needed, clear 2nd level interrupt source */1919+ void (*clear_penirq)(void);2020 int (*init_platform_hw)(void);2121 void (*exit_platform_hw)(void);2222};