Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Driver for Himax hx83112b touchscreens
  4 *
  5 * Copyright (C) 2022 Job Noorman <job@noorman.info>
  6 *
  7 * HX83100A support
  8 * Copyright (C) 2024 Felix Kaechele <felix@kaechele.ca>
  9 *
 10 * This code is based on "Himax Android Driver Sample Code for QCT platform":
 11 *
 12 * Copyright (C) 2017 Himax Corporation.
 13 */
 14
 15#include <linux/delay.h>
 16#include <linux/err.h>
 17#include <linux/gpio/consumer.h>
 18#include <linux/i2c.h>
 19#include <linux/input.h>
 20#include <linux/input/mt.h>
 21#include <linux/input/touchscreen.h>
 22#include <linux/interrupt.h>
 23#include <linux/kernel.h>
 24#include <linux/regmap.h>
 25
 26#define HIMAX_MAX_POINTS		10
 27
 28#define HIMAX_AHB_ADDR_BYTE_0			0x00
 29#define HIMAX_AHB_ADDR_RDATA_BYTE_0		0x08
 30#define HIMAX_AHB_ADDR_ACCESS_DIRECTION		0x0c
 31#define HIMAX_AHB_ADDR_INCR4			0x0d
 32#define HIMAX_AHB_ADDR_CONTI			0x13
 33#define HIMAX_AHB_ADDR_EVENT_STACK		0x30
 34
 35#define HIMAX_AHB_CMD_ACCESS_DIRECTION_READ	0x00
 36#define HIMAX_AHB_CMD_INCR4			0x10
 37#define HIMAX_AHB_CMD_CONTI			0x31
 38
 39#define HIMAX_REG_ADDR_ICID			0x900000d0
 
 
 
 40
 41#define HX83100A_REG_FW_EVENT_STACK		0x90060000
 42
 43#define HIMAX_INVALID_COORD		0xffff
 44
 45struct himax_event_point {
 46	__be16 x;
 47	__be16 y;
 48} __packed;
 49
 50struct himax_event {
 51	struct himax_event_point points[HIMAX_MAX_POINTS];
 52	u8 majors[HIMAX_MAX_POINTS];
 53	u8 pad0[2];
 54	u8 num_points;
 55	u8 pad1[2];
 56	u8 checksum_fix;
 57} __packed;
 58
 59static_assert(sizeof(struct himax_event) == 56);
 60
 61struct himax_ts_data;
 62struct himax_chip {
 63	u32 id;
 64	int (*check_id)(struct himax_ts_data *ts);
 65	int (*read_events)(struct himax_ts_data *ts, struct himax_event *event,
 66			   size_t length);
 67};
 68
 69struct himax_ts_data {
 70	const struct himax_chip *chip;
 71	struct gpio_desc *gpiod_rst;
 72	struct input_dev *input_dev;
 73	struct i2c_client *client;
 74	struct regmap *regmap;
 75	struct touchscreen_properties props;
 76};
 77
 78static const struct regmap_config himax_regmap_config = {
 79	.reg_bits = 8,
 80	.val_bits = 32,
 81	.val_format_endian = REGMAP_ENDIAN_LITTLE,
 82};
 83
 84static int himax_bus_enable_burst(struct himax_ts_data *ts)
 85{
 86	int error;
 87
 88	error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_CONTI,
 89			     HIMAX_AHB_CMD_CONTI);
 90	if (error)
 91		return error;
 92
 93	error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_INCR4,
 94			     HIMAX_AHB_CMD_INCR4);
 95	if (error)
 96		return error;
 97
 98	return 0;
 99}
100
101static int himax_bus_read(struct himax_ts_data *ts, u32 address, void *dst,
102			  size_t length)
103{
104	int error;
105
106	if (length > 4) {
107		error = himax_bus_enable_burst(ts);
108		if (error)
109			return error;
110	}
111
112	error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_BYTE_0, address);
113	if (error)
114		return error;
115
116	error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_ACCESS_DIRECTION,
117			     HIMAX_AHB_CMD_ACCESS_DIRECTION_READ);
118	if (error)
119		return error;
120
121	if (length > 4)
122		error = regmap_noinc_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0,
123					  dst, length);
124	else
125		error = regmap_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0,
126				    dst);
127	if (error)
128		return error;
129
130	return 0;
131}
132
133static void himax_reset(struct himax_ts_data *ts)
134{
135	gpiod_set_value_cansleep(ts->gpiod_rst, 1);
136
137	/* Delay copied from downstream driver */
138	msleep(20);
139	gpiod_set_value_cansleep(ts->gpiod_rst, 0);
140
141	/*
142	 * The downstream driver doesn't contain this delay but is seems safer
143	 * to include it. The range is just a guess that seems to work well.
144	 */
145	usleep_range(1000, 1100);
146}
147
148static int himax_read_product_id(struct himax_ts_data *ts, u32 *product_id)
149{
150	int error;
151
152	error = himax_bus_read(ts, HIMAX_REG_ADDR_ICID, product_id,
153			       sizeof(*product_id));
154	if (error)
155		return error;
156
157	*product_id >>= 8;
158	return 0;
159}
160
161static int himax_check_product_id(struct himax_ts_data *ts)
162{
163	int error;
164	u32 product_id;
165
166	error = himax_read_product_id(ts, &product_id);
167	if (error)
168		return error;
169
170	dev_dbg(&ts->client->dev, "Product id: %x\n", product_id);
171
172	if (product_id == ts->chip->id)
 
173		return 0;
174
175	dev_err(&ts->client->dev, "Unknown product id: %x\n",
176		product_id);
177	return -EINVAL;
 
 
178}
179
180static int himax_input_register(struct himax_ts_data *ts)
181{
182	int error;
183
184	ts->input_dev = devm_input_allocate_device(&ts->client->dev);
185	if (!ts->input_dev) {
186		dev_err(&ts->client->dev, "Failed to allocate input device\n");
187		return -ENOMEM;
188	}
189
190	ts->input_dev->name = "Himax Touchscreen";
191
192	input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_X);
193	input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_Y);
194	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
195	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 200, 0, 0);
196
197	touchscreen_parse_properties(ts->input_dev, true, &ts->props);
198
199	error = input_mt_init_slots(ts->input_dev, HIMAX_MAX_POINTS,
200				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
201	if (error) {
202		dev_err(&ts->client->dev,
203			"Failed to initialize MT slots: %d\n", error);
204		return error;
205	}
206
207	error = input_register_device(ts->input_dev);
208	if (error) {
209		dev_err(&ts->client->dev,
210			"Failed to register input device: %d\n", error);
211		return error;
212	}
213
214	return 0;
215}
216
217static u8 himax_event_get_num_points(const struct himax_event *event)
218{
219	if (event->num_points == 0xff)
220		return 0;
221	else
222		return event->num_points & 0x0f;
223}
224
225static bool himax_process_event_point(struct himax_ts_data *ts,
226				      const struct himax_event *event,
227				      int point_index)
228{
229	const struct himax_event_point *point = &event->points[point_index];
230	u16 x = be16_to_cpu(point->x);
231	u16 y = be16_to_cpu(point->y);
232	u8 w = event->majors[point_index];
233
234	if (x == HIMAX_INVALID_COORD || y == HIMAX_INVALID_COORD)
235		return false;
236
237	input_mt_slot(ts->input_dev, point_index);
238	input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
239	touchscreen_report_pos(ts->input_dev, &ts->props, x, y, true);
240	input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);
241	input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
242	return true;
243}
244
245static void himax_process_event(struct himax_ts_data *ts,
246				const struct himax_event *event)
247{
248	int i;
249	int num_points_left = himax_event_get_num_points(event);
250
251	for (i = 0; i < HIMAX_MAX_POINTS && num_points_left > 0; i++) {
252		if (himax_process_event_point(ts, event, i))
253			num_points_left--;
254	}
255
256	input_mt_sync_frame(ts->input_dev);
257	input_sync(ts->input_dev);
258}
259
260static bool himax_verify_checksum(struct himax_ts_data *ts,
261				  const struct himax_event *event)
262{
263	u8 *data = (u8 *)event;
264	int i;
265	u16 checksum = 0;
266
267	for (i = 0; i < sizeof(*event); i++)
268		checksum += data[i];
269
270	if ((checksum & 0x00ff) != 0) {
271		dev_err(&ts->client->dev, "Wrong event checksum: %04x\n",
272			checksum);
273		return false;
274	}
275
276	return true;
277}
278
279static int himax_read_events(struct himax_ts_data *ts,
280			     struct himax_event *event, size_t length)
281{
282	return regmap_raw_read(ts->regmap, HIMAX_AHB_ADDR_EVENT_STACK, event,
283			       length);
284}
285
286static int hx83100a_read_events(struct himax_ts_data *ts,
287				struct himax_event *event, size_t length)
288{
289	return himax_bus_read(ts, HX83100A_REG_FW_EVENT_STACK, event, length);
290};
291
292static int himax_handle_input(struct himax_ts_data *ts)
293{
294	int error;
295	struct himax_event event;
296
297	error = ts->chip->read_events(ts, &event, sizeof(event));
 
298	if (error) {
299		dev_err(&ts->client->dev, "Failed to read input event: %d\n",
300			error);
301		return error;
302	}
303
304	/*
305	 * Only process the current event when it has a valid checksum but
306	 * don't consider it a fatal error when it doesn't.
307	 */
308	if (himax_verify_checksum(ts, &event))
309		himax_process_event(ts, &event);
310
311	return 0;
312}
313
314static irqreturn_t himax_irq_handler(int irq, void *dev_id)
315{
316	int error;
317	struct himax_ts_data *ts = dev_id;
318
319	error = himax_handle_input(ts);
320	if (error)
321		return IRQ_NONE;
322
323	return IRQ_HANDLED;
324}
325
326static int himax_probe(struct i2c_client *client)
327{
328	int error;
329	struct device *dev = &client->dev;
330	struct himax_ts_data *ts;
331
332	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
333		dev_err(dev, "I2C check functionality failed\n");
334		return -ENXIO;
335	}
336
337	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
338	if (!ts)
339		return -ENOMEM;
340
341	i2c_set_clientdata(client, ts);
342	ts->client = client;
343	ts->chip = i2c_get_match_data(client);
344
345	ts->regmap = devm_regmap_init_i2c(client, &himax_regmap_config);
346	error = PTR_ERR_OR_ZERO(ts->regmap);
347	if (error) {
348		dev_err(dev, "Failed to initialize regmap: %d\n", error);
349		return error;
350	}
351
352	ts->gpiod_rst = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
353	error = PTR_ERR_OR_ZERO(ts->gpiod_rst);
354	if (error) {
355		dev_err(dev, "Failed to get reset GPIO: %d\n", error);
356		return error;
357	}
358
359	himax_reset(ts);
360
361	if (ts->chip->check_id) {
362		error = himax_check_product_id(ts);
363		if (error)
364			return error;
365	}
366
367	error = himax_input_register(ts);
368	if (error)
369		return error;
370
371	error = devm_request_threaded_irq(dev, client->irq, NULL,
372					  himax_irq_handler, IRQF_ONESHOT,
373					  client->name, ts);
374	if (error)
375		return error;
376
377	return 0;
378}
379
380static int himax_suspend(struct device *dev)
381{
382	struct himax_ts_data *ts = dev_get_drvdata(dev);
383
384	disable_irq(ts->client->irq);
385	return 0;
386}
387
388static int himax_resume(struct device *dev)
389{
390	struct himax_ts_data *ts = dev_get_drvdata(dev);
391
392	enable_irq(ts->client->irq);
393	return 0;
394}
395
396static DEFINE_SIMPLE_DEV_PM_OPS(himax_pm_ops, himax_suspend, himax_resume);
397
398static const struct himax_chip hx83100a_chip = {
399	.read_events = hx83100a_read_events,
400};
401
402static const struct himax_chip hx83112b_chip = {
403	.id = 0x83112b,
404	.check_id = himax_check_product_id,
405	.read_events = himax_read_events,
406};
407
408static const struct i2c_device_id himax_ts_id[] = {
409	{ "hx83100a", (kernel_ulong_t)&hx83100a_chip },
410	{ "hx83112b", (kernel_ulong_t)&hx83112b_chip },
411	{ /* sentinel */ }
412};
413MODULE_DEVICE_TABLE(i2c, himax_ts_id);
414
415#ifdef CONFIG_OF
416static const struct of_device_id himax_of_match[] = {
417	{ .compatible = "himax,hx83100a", .data = &hx83100a_chip },
418	{ .compatible = "himax,hx83112b", .data = &hx83112b_chip },
419	{ /* sentinel */ }
420};
421MODULE_DEVICE_TABLE(of, himax_of_match);
422#endif
423
424static struct i2c_driver himax_ts_driver = {
425	.probe = himax_probe,
426	.id_table = himax_ts_id,
427	.driver = {
428		.name = "Himax-hx83112b-TS",
429		.of_match_table = of_match_ptr(himax_of_match),
430		.pm = pm_sleep_ptr(&himax_pm_ops),
431	},
432};
433module_i2c_driver(himax_ts_driver);
434
435MODULE_AUTHOR("Job Noorman <job@noorman.info>");
436MODULE_DESCRIPTION("Himax hx83112b touchscreen driver");
437MODULE_LICENSE("GPL");
v6.2
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Driver for Himax hx83112b touchscreens
  4 *
  5 * Copyright (C) 2022 Job Noorman <job@noorman.info>
  6 *
 
 
 
  7 * This code is based on "Himax Android Driver Sample Code for QCT platform":
  8 *
  9 * Copyright (C) 2017 Himax Corporation.
 10 */
 11
 12#include <linux/delay.h>
 13#include <linux/err.h>
 14#include <linux/gpio/consumer.h>
 15#include <linux/i2c.h>
 16#include <linux/input.h>
 17#include <linux/input/mt.h>
 18#include <linux/input/touchscreen.h>
 19#include <linux/interrupt.h>
 20#include <linux/kernel.h>
 21#include <linux/regmap.h>
 22
 23#define HIMAX_ID_83112B			0x83112b
 24
 25#define HIMAX_MAX_POINTS		10
 
 
 
 
 
 
 
 
 
 26
 27#define HIMAX_REG_CFG_SET_ADDR		0x00
 28#define HIMAX_REG_CFG_INIT_READ		0x0c
 29#define HIMAX_REG_CFG_READ_VALUE	0x08
 30#define HIMAX_REG_READ_EVENT		0x30
 31
 32#define HIMAX_CFG_PRODUCT_ID		0x900000d0
 33
 34#define HIMAX_INVALID_COORD		0xffff
 35
 36struct himax_event_point {
 37	__be16 x;
 38	__be16 y;
 39} __packed;
 40
 41struct himax_event {
 42	struct himax_event_point points[HIMAX_MAX_POINTS];
 43	u8 majors[HIMAX_MAX_POINTS];
 44	u8 pad0[2];
 45	u8 num_points;
 46	u8 pad1[2];
 47	u8 checksum_fix;
 48} __packed;
 49
 50static_assert(sizeof(struct himax_event) == 56);
 51
 
 
 
 
 
 
 
 
 52struct himax_ts_data {
 
 53	struct gpio_desc *gpiod_rst;
 54	struct input_dev *input_dev;
 55	struct i2c_client *client;
 56	struct regmap *regmap;
 57	struct touchscreen_properties props;
 58};
 59
 60static const struct regmap_config himax_regmap_config = {
 61	.reg_bits = 8,
 62	.val_bits = 32,
 63	.val_format_endian = REGMAP_ENDIAN_LITTLE,
 64};
 65
 66static int himax_read_config(struct himax_ts_data *ts, u32 address, u32 *dst)
 67{
 68	int error;
 69
 70	error = regmap_write(ts->regmap, HIMAX_REG_CFG_SET_ADDR, address);
 
 71	if (error)
 72		return error;
 73
 74	error = regmap_write(ts->regmap, HIMAX_REG_CFG_INIT_READ, 0x0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 75	if (error)
 76		return error;
 77
 78	error = regmap_read(ts->regmap, HIMAX_REG_CFG_READ_VALUE, dst);
 
 
 
 
 
 
 
 
 
 
 79	if (error)
 80		return error;
 81
 82	return 0;
 83}
 84
 85static void himax_reset(struct himax_ts_data *ts)
 86{
 87	gpiod_set_value_cansleep(ts->gpiod_rst, 1);
 88
 89	/* Delay copied from downstream driver */
 90	msleep(20);
 91	gpiod_set_value_cansleep(ts->gpiod_rst, 0);
 92
 93	/*
 94	 * The downstream driver doesn't contain this delay but is seems safer
 95	 * to include it. The range is just a guess that seems to work well.
 96	 */
 97	usleep_range(1000, 1100);
 98}
 99
100static int himax_read_product_id(struct himax_ts_data *ts, u32 *product_id)
101{
102	int error;
103
104	error = himax_read_config(ts, HIMAX_CFG_PRODUCT_ID, product_id);
 
105	if (error)
106		return error;
107
108	*product_id >>= 8;
109	return 0;
110}
111
112static int himax_check_product_id(struct himax_ts_data *ts)
113{
114	int error;
115	u32 product_id;
116
117	error = himax_read_product_id(ts, &product_id);
118	if (error)
119		return error;
120
121	dev_dbg(&ts->client->dev, "Product id: %x\n", product_id);
122
123	switch (product_id) {
124	case HIMAX_ID_83112B:
125		return 0;
126
127	default:
128		dev_err(&ts->client->dev,
129			"Unknown product id: %x\n", product_id);
130		return -EINVAL;
131	}
132}
133
134static int himax_input_register(struct himax_ts_data *ts)
135{
136	int error;
137
138	ts->input_dev = devm_input_allocate_device(&ts->client->dev);
139	if (!ts->input_dev) {
140		dev_err(&ts->client->dev, "Failed to allocate input device\n");
141		return -ENOMEM;
142	}
143
144	ts->input_dev->name = "Himax Touchscreen";
145
146	input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_X);
147	input_set_capability(ts->input_dev, EV_ABS, ABS_MT_POSITION_Y);
148	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
149	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 200, 0, 0);
150
151	touchscreen_parse_properties(ts->input_dev, true, &ts->props);
152
153	error = input_mt_init_slots(ts->input_dev, HIMAX_MAX_POINTS,
154				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
155	if (error) {
156		dev_err(&ts->client->dev,
157			"Failed to initialize MT slots: %d\n", error);
158		return error;
159	}
160
161	error = input_register_device(ts->input_dev);
162	if (error) {
163		dev_err(&ts->client->dev,
164			"Failed to register input device: %d\n", error);
165		return error;
166	}
167
168	return 0;
169}
170
171static u8 himax_event_get_num_points(const struct himax_event *event)
172{
173	if (event->num_points == 0xff)
174		return 0;
175	else
176		return event->num_points & 0x0f;
177}
178
179static bool himax_process_event_point(struct himax_ts_data *ts,
180				      const struct himax_event *event,
181				      int point_index)
182{
183	const struct himax_event_point *point = &event->points[point_index];
184	u16 x = be16_to_cpu(point->x);
185	u16 y = be16_to_cpu(point->y);
186	u8 w = event->majors[point_index];
187
188	if (x == HIMAX_INVALID_COORD || y == HIMAX_INVALID_COORD)
189		return false;
190
191	input_mt_slot(ts->input_dev, point_index);
192	input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
193	touchscreen_report_pos(ts->input_dev, &ts->props, x, y, true);
194	input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);
195	input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
196	return true;
197}
198
199static void himax_process_event(struct himax_ts_data *ts,
200				const struct himax_event *event)
201{
202	int i;
203	int num_points_left = himax_event_get_num_points(event);
204
205	for (i = 0; i < HIMAX_MAX_POINTS && num_points_left > 0; i++) {
206		if (himax_process_event_point(ts, event, i))
207			num_points_left--;
208	}
209
210	input_mt_sync_frame(ts->input_dev);
211	input_sync(ts->input_dev);
212}
213
214static bool himax_verify_checksum(struct himax_ts_data *ts,
215				  const struct himax_event *event)
216{
217	u8 *data = (u8 *)event;
218	int i;
219	u16 checksum = 0;
220
221	for (i = 0; i < sizeof(*event); i++)
222		checksum += data[i];
223
224	if ((checksum & 0x00ff) != 0) {
225		dev_err(&ts->client->dev, "Wrong event checksum: %04x\n",
226			checksum);
227		return false;
228	}
229
230	return true;
231}
232
 
 
 
 
 
 
 
 
 
 
 
 
 
233static int himax_handle_input(struct himax_ts_data *ts)
234{
235	int error;
236	struct himax_event event;
237
238	error = regmap_raw_read(ts->regmap, HIMAX_REG_READ_EVENT, &event,
239				sizeof(event));
240	if (error) {
241		dev_err(&ts->client->dev, "Failed to read input event: %d\n",
242			error);
243		return error;
244	}
245
246	/*
247	 * Only process the current event when it has a valid checksum but
248	 * don't consider it a fatal error when it doesn't.
249	 */
250	if (himax_verify_checksum(ts, &event))
251		himax_process_event(ts, &event);
252
253	return 0;
254}
255
256static irqreturn_t himax_irq_handler(int irq, void *dev_id)
257{
258	int error;
259	struct himax_ts_data *ts = dev_id;
260
261	error = himax_handle_input(ts);
262	if (error)
263		return IRQ_NONE;
264
265	return IRQ_HANDLED;
266}
267
268static int himax_probe(struct i2c_client *client)
269{
270	int error;
271	struct device *dev = &client->dev;
272	struct himax_ts_data *ts;
273
274	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
275		dev_err(dev, "I2C check functionality failed\n");
276		return -ENXIO;
277	}
278
279	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
280	if (!ts)
281		return -ENOMEM;
282
283	i2c_set_clientdata(client, ts);
284	ts->client = client;
 
285
286	ts->regmap = devm_regmap_init_i2c(client, &himax_regmap_config);
287	error = PTR_ERR_OR_ZERO(ts->regmap);
288	if (error) {
289		dev_err(dev, "Failed to initialize regmap: %d\n", error);
290		return error;
291	}
292
293	ts->gpiod_rst = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
294	error = PTR_ERR_OR_ZERO(ts->gpiod_rst);
295	if (error) {
296		dev_err(dev, "Failed to get reset GPIO: %d\n", error);
297		return error;
298	}
299
300	himax_reset(ts);
301
302	error = himax_check_product_id(ts);
303	if (error)
304		return error;
 
 
305
306	error = himax_input_register(ts);
307	if (error)
308		return error;
309
310	error = devm_request_threaded_irq(dev, client->irq, NULL,
311					  himax_irq_handler, IRQF_ONESHOT,
312					  client->name, ts);
313	if (error)
314		return error;
315
316	return 0;
317}
318
319static int himax_suspend(struct device *dev)
320{
321	struct himax_ts_data *ts = dev_get_drvdata(dev);
322
323	disable_irq(ts->client->irq);
324	return 0;
325}
326
327static int himax_resume(struct device *dev)
328{
329	struct himax_ts_data *ts = dev_get_drvdata(dev);
330
331	enable_irq(ts->client->irq);
332	return 0;
333}
334
335static DEFINE_SIMPLE_DEV_PM_OPS(himax_pm_ops, himax_suspend, himax_resume);
336
 
 
 
 
 
 
 
 
 
 
337static const struct i2c_device_id himax_ts_id[] = {
338	{ "hx83112b", 0 },
 
339	{ /* sentinel */ }
340};
341MODULE_DEVICE_TABLE(i2c, himax_ts_id);
342
343#ifdef CONFIG_OF
344static const struct of_device_id himax_of_match[] = {
345	{ .compatible = "himax,hx83112b" },
 
346	{ /* sentinel */ }
347};
348MODULE_DEVICE_TABLE(of, himax_of_match);
349#endif
350
351static struct i2c_driver himax_ts_driver = {
352	.probe_new = himax_probe,
353	.id_table = himax_ts_id,
354	.driver = {
355		.name = "Himax-hx83112b-TS",
356		.of_match_table = of_match_ptr(himax_of_match),
357		.pm = pm_sleep_ptr(&himax_pm_ops),
358	},
359};
360module_i2c_driver(himax_ts_driver);
361
362MODULE_AUTHOR("Job Noorman <job@noorman.info>");
363MODULE_DESCRIPTION("Himax hx83112b touchscreen driver");
364MODULE_LICENSE("GPL");