1 /*
2 * cyttsp5_devtree.c
3 * Parade TrueTouch(TM) Standard Product V5 Device Tree Support Module.
4 * For use with Parade touchscreen controllers.
5 * Supported parts include:
6 * CYTMA5XX
7 * CYTMA448
8 * CYTMA445A
9 * CYTT21XXX
10 * CYTT31XXX
11 *
12 * Copyright (C) 2015 Parade Technologies
13 * Copyright (C) 2013-2015 Cypress Semiconductor
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2, and only version 2, as published by the
18 * Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * Contact Parade Technologies at www.paradetech.com <ttdrivers@paradetech.com>
26 *
27 */
28
29 #include <linux/device.h>
30 #include <linux/err.h>
31 #include <linux/of_device.h>
32 #include <linux/slab.h>
33 #include <linux/of_gpio.h>
34
35 /* cyttsp */
36 #include "cyttsp5_regs.h"
37 #include "cyttsp5_platform.h"
38
39 //#define ENABLE_VIRTUAL_KEYS
40
41 #define MAX_NAME_LENGTH 64
42
43 enum cyttsp5_device_type {
44 DEVICE_MT,
45 DEVICE_BTN,
46 DEVICE_PROXIMITY,
47 DEVICE_TYPE_MAX,
48 };
49
50
51 struct cyttsp5_device_pdata_func {
52 void * (*create_and_get_pdata)(struct device_node *);
53 void (*free_pdata)(void *);
54 };
55
56 struct cyttsp5_pdata_ptr {
57 void **pdata;
58 };
59
60 #ifdef ENABLE_VIRTUAL_KEYS
61 static struct kobject *board_properties_kobj;
62
63 struct cyttsp5_virtual_keys {
64 struct kobj_attribute kobj_attr;
65 u16 *data;
66 int size;
67 };
68 #endif
69
70 struct cyttsp5_extended_mt_platform_data {
71 struct cyttsp5_mt_platform_data pdata;
72 #ifdef ENABLE_VIRTUAL_KEYS
73 struct cyttsp5_virtual_keys vkeys;
74 #endif
75 };
76
get_inp_dev_name(struct device_node * dev_node,const char ** inp_dev_name)77 static inline int get_inp_dev_name(struct device_node *dev_node,
78 const char **inp_dev_name)
79 {
80 return of_property_read_string(dev_node, "cy,inp_dev_name",
81 inp_dev_name);
82 }
83
create_and_get_u16_array(struct device_node * dev_node,const char * name,int * size)84 static s16 *create_and_get_u16_array(struct device_node *dev_node,
85 const char *name, int *size)
86 {
87 const __be32 *values;
88 s16 *val_array;
89 int len;
90 int sz;
91 int rc;
92 int i;
93
94 values = of_get_property(dev_node, name, &len);
95 if (values == NULL)
96 return NULL;
97
98 sz = len / sizeof(u32);
99 pr_debug("%s: %s size:%d\n", __func__, name, sz);
100
101 val_array = kcalloc(sz, sizeof(s16), GFP_KERNEL);
102 if (!val_array) {
103 rc = -ENOMEM;
104 goto fail;
105 }
106 //printk("create_and_get_u16_array\n");
107 for (i = 0; i < sz; i++){
108 val_array[i] = (s16)be32_to_cpup(values++);
109 //printk("%d ", val_array[i]);
110
111 }
112 //printk("\ncreate_and_get_u16_array\n");
113
114 *size = sz;
115
116 return val_array;
117
118 fail:
119 return ERR_PTR(rc);
120 }
121
create_and_get_touch_framework(struct device_node * dev_node)122 static struct touch_framework *create_and_get_touch_framework(
123 struct device_node *dev_node)
124 {
125 struct touch_framework *frmwrk;
126 s16 *abs;
127 int size;
128 int rc;
129
130 abs = create_and_get_u16_array(dev_node, "cy,abs", &size);
131 if (IS_ERR_OR_NULL(abs))
132 return (void *)abs;
133
134 /* Check for valid abs size */
135 if (size % CY_NUM_ABS_SET) {
136 rc = -EINVAL;
137 goto fail_free_abs;
138 }
139
140 frmwrk = kzalloc(sizeof(*frmwrk), GFP_KERNEL);
141 if (!frmwrk) {
142 rc = -ENOMEM;
143 goto fail_free_abs;
144 }
145
146 frmwrk->abs = abs;
147 frmwrk->size = size;
148
149 return frmwrk;
150
151 fail_free_abs:
152 kfree(abs);
153
154 return ERR_PTR(rc);
155 }
156
free_touch_framework(struct touch_framework * frmwrk)157 static void free_touch_framework(struct touch_framework *frmwrk)
158 {
159 kfree(frmwrk->abs);
160 kfree(frmwrk);
161 }
162
163 #ifdef ENABLE_VIRTUAL_KEYS
164 #define VIRTUAL_KEY_ELEMENT_SIZE 5
virtual_keys_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)165 static ssize_t virtual_keys_show(struct kobject *kobj,
166 struct kobj_attribute *attr, char *buf)
167 {
168 struct cyttsp5_virtual_keys *vkeys = container_of(attr,
169 struct cyttsp5_virtual_keys, kobj_attr);
170 u16 *data = vkeys->data;
171 int size = vkeys->size;
172 int index;
173 int i;
174
175 index = 0;
176 for (i = 0; i < size; i += VIRTUAL_KEY_ELEMENT_SIZE)
177 index += scnprintf(buf + index, CY_MAX_PRBUF_SIZE - index,
178 "0x01:%d:%d:%d:%d:%d\n",
179 data[i], data[i+1], data[i+2], data[i+3], data[i+4]);
180
181 return index;
182 }
183
setup_virtual_keys(struct device_node * dev_node,const char * inp_dev_name,struct cyttsp5_virtual_keys * vkeys)184 static int setup_virtual_keys(struct device_node *dev_node,
185 const char *inp_dev_name, struct cyttsp5_virtual_keys *vkeys)
186 {
187 char *name;
188 u16 *data;
189 int size;
190 int rc;
191
192 data = create_and_get_u16_array(dev_node, "cy,virtual_keys", &size);
193 if (data == NULL)
194 return 0;
195 else if (IS_ERR(data)) {
196 rc = PTR_ERR(data);
197 goto fail;
198 }
199
200 /* Check for valid virtual keys size */
201 if (size % VIRTUAL_KEY_ELEMENT_SIZE) {
202 rc = -EINVAL;
203 goto fail_free_data;
204 }
205
206 name = kzalloc(MAX_NAME_LENGTH, GFP_KERNEL);
207 if (!name) {
208 rc = -ENOMEM;
209 goto fail_free_data;
210 }
211
212 snprintf(name, MAX_NAME_LENGTH, "virtualkeys.%s", inp_dev_name);
213
214 vkeys->data = data;
215 vkeys->size = size;
216
217 /* TODO: Instantiate in board file and export it */
218 if (board_properties_kobj == NULL)
219 board_properties_kobj =
220 kobject_create_and_add("board_properties", NULL);
221 if (board_properties_kobj == NULL) {
222 pr_err("%s: Cannot get board_properties kobject!\n", __func__);
223 rc = -EINVAL;
224 goto fail_free_name;
225 }
226
227 /* Initialize dynamic SysFs attribute */
228 sysfs_attr_init(&vkeys->kobj_attr.attr);
229 vkeys->kobj_attr.attr.name = name;
230 vkeys->kobj_attr.attr.mode = S_IRUGO;
231 vkeys->kobj_attr.show = virtual_keys_show;
232
233 rc = sysfs_create_file(board_properties_kobj, &vkeys->kobj_attr.attr);
234 if (rc)
235 goto fail_del_kobj;
236
237 return 0;
238
239 fail_del_kobj:
240 kobject_del(board_properties_kobj);
241 fail_free_name:
242 kfree(name);
243 vkeys->kobj_attr.attr.name = NULL;
244 fail_free_data:
245 kfree(data);
246 vkeys->data = NULL;
247 fail:
248 return rc;
249 }
250
free_virtual_keys(struct cyttsp5_virtual_keys * vkeys)251 static void free_virtual_keys(struct cyttsp5_virtual_keys *vkeys)
252 {
253 if (board_properties_kobj)
254 sysfs_remove_file(board_properties_kobj,
255 &vkeys->kobj_attr.attr);
256
257
258 kobject_del(board_properties_kobj);
259 board_properties_kobj = NULL;
260
261 kfree(vkeys->data);
262 kfree(vkeys->kobj_attr.attr.name);
263 }
264 #endif
265
create_and_get_mt_pdata(struct device_node * dev_node)266 static void *create_and_get_mt_pdata(struct device_node *dev_node)
267 {
268 struct cyttsp5_extended_mt_platform_data *ext_pdata;
269 struct cyttsp5_mt_platform_data *pdata;
270 u32 value;
271 int rc;
272
273 ext_pdata = kzalloc(sizeof(*ext_pdata), GFP_KERNEL);
274 if (!ext_pdata) {
275 rc = -ENOMEM;
276 goto fail;
277 }
278
279 pdata = &ext_pdata->pdata;
280
281 rc = get_inp_dev_name(dev_node, &pdata->inp_dev_name);
282 if (rc)
283 goto fail_free_pdata;
284
285 /* Optional fields */
286 rc = of_property_read_u32(dev_node, "cy,flags", &value);
287 if (!rc)
288 pdata->flags = value;
289
290 rc = of_property_read_u32(dev_node, "cy,vkeys_x", &value);
291 if (!rc)
292 pdata->vkeys_x = value;
293
294 rc = of_property_read_u32(dev_node, "cy,vkeys_y", &value);
295 if (!rc)
296 pdata->vkeys_y = value;
297
298 rc = of_property_read_u32(dev_node, "cy,revert_x", &value);
299 if (!rc)
300 pdata->swap_x = value;
301 rc = of_property_read_u32(dev_node, "cy,revert_y", &value);
302 if (!rc)
303 pdata->swap_y = value;
304 rc = of_property_read_u32(dev_node, "cy,xy_exchange", &value);
305 if (!rc)
306 pdata->xy_exchange = value;
307
308
309 /* Required fields */
310 pdata->frmwrk = create_and_get_touch_framework(dev_node);
311 if (pdata->frmwrk == NULL) {
312 rc = -EINVAL;
313 goto fail_free_pdata;
314 } else if (IS_ERR(pdata->frmwrk)) {
315 rc = PTR_ERR(pdata->frmwrk);
316 goto fail_free_pdata;
317 }
318 #ifdef ENABLE_VIRTUAL_KEYS
319 rc = setup_virtual_keys(dev_node, pdata->inp_dev_name,
320 &ext_pdata->vkeys);
321 if (rc) {
322 pr_err("%s: Cannot setup virtual keys!\n", __func__);
323 goto fail_free_pdata;
324 }
325 #endif
326 return pdata;
327
328 fail_free_pdata:
329 kfree(ext_pdata);
330 fail:
331 return ERR_PTR(rc);
332 }
333
free_mt_pdata(void * pdata)334 static void free_mt_pdata(void *pdata)
335 {
336 struct cyttsp5_mt_platform_data *mt_pdata =
337 (struct cyttsp5_mt_platform_data *)pdata;
338 struct cyttsp5_extended_mt_platform_data *ext_mt_pdata =
339 container_of(mt_pdata,
340 struct cyttsp5_extended_mt_platform_data, pdata);
341
342 free_touch_framework(mt_pdata->frmwrk);
343 #ifdef ENABLE_VIRTUAL_KEYS
344 free_virtual_keys(&ext_mt_pdata->vkeys);
345 #endif
346 kfree(ext_mt_pdata);
347 }
348
create_and_get_btn_pdata(struct device_node * dev_node)349 static void *create_and_get_btn_pdata(struct device_node *dev_node)
350 {
351 struct cyttsp5_btn_platform_data *pdata;
352 int rc;
353
354 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
355 if (!pdata) {
356 rc = -ENOMEM;
357 goto fail;
358 }
359
360 rc = get_inp_dev_name(dev_node, &pdata->inp_dev_name);
361 if (rc)
362 goto fail_free_pdata;
363
364 return pdata;
365
366 fail_free_pdata:
367 kfree(pdata);
368 fail:
369 return ERR_PTR(rc);
370 }
371
free_btn_pdata(void * pdata)372 static void free_btn_pdata(void *pdata)
373 {
374 struct cyttsp5_btn_platform_data *btn_pdata =
375 (struct cyttsp5_btn_platform_data *)pdata;
376
377 kfree(btn_pdata);
378 }
379
create_and_get_proximity_pdata(struct device_node * dev_node)380 static void *create_and_get_proximity_pdata(struct device_node *dev_node)
381 {
382 struct cyttsp5_proximity_platform_data *pdata;
383 int rc;
384
385 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
386 if (!pdata) {
387 rc = -ENOMEM;
388 goto fail;
389 }
390
391 rc = get_inp_dev_name(dev_node, &pdata->inp_dev_name);
392 if (rc)
393 goto fail_free_pdata;
394
395 pdata->frmwrk = create_and_get_touch_framework(dev_node);
396 if (pdata->frmwrk == NULL) {
397 rc = -EINVAL;
398 goto fail_free_pdata;
399 } else if (IS_ERR(pdata->frmwrk)) {
400 rc = PTR_ERR(pdata->frmwrk);
401 goto fail_free_pdata;
402 }
403
404 return pdata;
405
406 fail_free_pdata:
407 kfree(pdata);
408 fail:
409 return ERR_PTR(rc);
410 }
411
free_proximity_pdata(void * pdata)412 static void free_proximity_pdata(void *pdata)
413 {
414 struct cyttsp5_proximity_platform_data *proximity_pdata =
415 (struct cyttsp5_proximity_platform_data *)pdata;
416
417 free_touch_framework(proximity_pdata->frmwrk);
418
419 kfree(proximity_pdata);
420 }
421
422 static struct cyttsp5_device_pdata_func device_pdata_funcs[DEVICE_TYPE_MAX] = {
423 [DEVICE_MT] = {
424 .create_and_get_pdata = create_and_get_mt_pdata,
425 .free_pdata = free_mt_pdata,
426 },
427 [DEVICE_BTN] = {
428 .create_and_get_pdata = create_and_get_btn_pdata,
429 .free_pdata = free_btn_pdata,
430 },
431 [DEVICE_PROXIMITY] = {
432 .create_and_get_pdata = create_and_get_proximity_pdata,
433 .free_pdata = free_proximity_pdata,
434 },
435 };
436
437 static struct cyttsp5_pdata_ptr pdata_ptr[DEVICE_TYPE_MAX];
438
439 static const char *device_names[DEVICE_TYPE_MAX] = {
440 [DEVICE_MT] = "cy,mt",
441 [DEVICE_BTN] = "cy,btn",
442 [DEVICE_PROXIMITY] = "cy,proximity",
443 };
444
set_pdata_ptr(struct cyttsp5_platform_data * pdata)445 static void set_pdata_ptr(struct cyttsp5_platform_data *pdata)
446 {
447 pdata_ptr[DEVICE_MT].pdata = (void **)&pdata->mt_pdata;
448 pdata_ptr[DEVICE_BTN].pdata = (void **)&pdata->btn_pdata;
449 pdata_ptr[DEVICE_PROXIMITY].pdata = (void **)&pdata->prox_pdata;
450 }
451
get_device_type(struct device_node * dev_node,enum cyttsp5_device_type * type)452 static int get_device_type(struct device_node *dev_node,
453 enum cyttsp5_device_type *type)
454 {
455 const char *name;
456 enum cyttsp5_device_type t;
457 int rc;
458
459 rc = of_property_read_string(dev_node, "name", &name);
460 if (rc)
461 return rc;
462
463 for (t = 0; t < DEVICE_TYPE_MAX; t++)
464 if (!strncmp(name, device_names[t], MAX_NAME_LENGTH)) {
465 *type = t;
466 return 0;
467 }
468
469 return -EINVAL;
470 }
471
create_and_get_device_pdata(struct device_node * dev_node,enum cyttsp5_device_type type)472 static inline void *create_and_get_device_pdata(struct device_node *dev_node,
473 enum cyttsp5_device_type type)
474 {
475 return device_pdata_funcs[type].create_and_get_pdata(dev_node);
476 }
477
free_device_pdata(enum cyttsp5_device_type type)478 static inline void free_device_pdata(enum cyttsp5_device_type type)
479 {
480 device_pdata_funcs[type].free_pdata(*pdata_ptr[type].pdata);
481 }
482
create_and_get_touch_setting(struct device_node * core_node,const char * name)483 static struct touch_settings *create_and_get_touch_setting(
484 struct device_node *core_node, const char *name)
485 {
486 struct touch_settings *setting;
487 char *tag_name;
488 u32 tag_value;
489 u16 *data;
490 int size;
491 int rc;
492
493 data = create_and_get_u16_array(core_node, name, &size);
494 if (IS_ERR_OR_NULL(data))
495 return (void *)data;
496
497 pr_debug("%s: Touch setting:'%s' size:%d\n", __func__, name, size);
498
499 setting = kzalloc(sizeof(*setting), GFP_KERNEL);
500 if (!setting) {
501 rc = -ENOMEM;
502 goto fail_free_data;
503 }
504
505 setting->data = (u8 *)data;
506 setting->size = size;
507
508 tag_name = kzalloc(MAX_NAME_LENGTH, GFP_KERNEL);
509 if (!tag_name) {
510 rc = -ENOMEM;
511 goto fail_free_setting;
512 }
513
514 snprintf(tag_name, MAX_NAME_LENGTH, "%s-tag", name);
515
516 rc = of_property_read_u32(core_node, tag_name, &tag_value);
517 if (!rc)
518 setting->tag = tag_value;
519
520 kfree(tag_name);
521
522 return setting;
523
524 fail_free_setting:
525 kfree(setting);
526 fail_free_data:
527 kfree(data);
528
529 return ERR_PTR(rc);
530 }
531
free_touch_setting(struct touch_settings * setting)532 static void free_touch_setting(struct touch_settings *setting)
533 {
534 if (setting) {
535 kfree(setting->data);
536 kfree(setting);
537 }
538 }
539
540 static char *touch_setting_names[CY_IC_GRPNUM_NUM] = {
541 NULL, /* CY_IC_GRPNUM_RESERVED */
542 "cy,cmd_regs", /* CY_IC_GRPNUM_CMD_REGS */
543 "cy,tch_rep", /* CY_IC_GRPNUM_TCH_REP */
544 "cy,data_rec", /* CY_IC_GRPNUM_DATA_REC */
545 "cy,test_rec", /* CY_IC_GRPNUM_TEST_REC */
546 "cy,pcfg_rec", /* CY_IC_GRPNUM_PCFG_REC */
547 "cy,tch_parm_val", /* CY_IC_GRPNUM_TCH_PARM_VAL */
548 "cy,tch_parm_size", /* CY_IC_GRPNUM_TCH_PARM_SIZE */
549 NULL, /* CY_IC_GRPNUM_RESERVED1 */
550 NULL, /* CY_IC_GRPNUM_RESERVED2 */
551 "cy,opcfg_rec", /* CY_IC_GRPNUM_OPCFG_REC */
552 "cy,ddata_rec", /* CY_IC_GRPNUM_DDATA_REC */
553 "cy,mdata_rec", /* CY_IC_GRPNUM_MDATA_REC */
554 "cy,test_regs", /* CY_IC_GRPNUM_TEST_REGS */
555 "cy,btn_keys", /* CY_IC_GRPNUM_BTN_KEYS */
556 NULL, /* CY_IC_GRPNUM_TTHE_REGS */
557 };
558
create_and_get_core_pdata(struct device_node * core_node)559 static struct cyttsp5_core_platform_data *create_and_get_core_pdata(
560 struct device_node *core_node)
561 {
562 struct cyttsp5_core_platform_data *pdata;
563 u32 value;
564 int rc;
565 int i;
566 int reset_gpio = -1, irq_gpio = -1, pwr_1v8_io = -1, pwr_2v8_io;
567
568 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
569 if (!pdata) {
570 rc = -ENOMEM;
571 goto fail;
572 }
573
574 /* Required fields */
575 irq_gpio = of_get_named_gpio(core_node, "cy,irq_gpio", 0);
576 if (gpio_is_valid(irq_gpio)) {
577 pdata->irq_gpio = irq_gpio;
578 }
579 /* Optional fields */
580 /* rst_gpio is optional since a platform may use
581 * power cycling instead of using the XRES pin
582 */
583
584 reset_gpio = of_get_named_gpio(core_node, "cy,rst_gpio", 0);
585 if (gpio_is_valid(reset_gpio)) {
586 pdata->rst_gpio = reset_gpio;
587 }
588 pwr_1v8_io = of_get_named_gpio(core_node, "cy,1v8_gpio", 0);
589 if (gpio_is_valid(pwr_1v8_io)) {
590 rc = gpio_request(pwr_1v8_io, NULL);
591 if (rc < 0) {
592 printk("pwr_1v8_io request failed,rc=%d\n", rc);
593 } else {
594 gpio_direction_output(pwr_1v8_io, 1);
595 }
596 }
597
598 pwr_2v8_io = of_get_named_gpio(core_node, "cy,2v8_gpio", 0);
599 if (gpio_is_valid(pwr_2v8_io)) {
600 rc = gpio_request(pwr_2v8_io, NULL);
601 if (rc < 0) {
602 printk("pwr_2v8_io request failed,rc=%d\n", rc);
603 } else {
604 gpio_direction_output(pwr_2v8_io, 1);
605 }
606 }
607
608 rc = of_property_read_u32(core_node, "cy,hid_desc_register", &value);
609 if (rc)
610 goto fail_free;
611 pdata->hid_desc_register = value;
612
613 rc = of_property_read_u32(core_node, "cy,level_irq_udelay", &value);
614 if (!rc)
615 pdata->level_irq_udelay = value;
616
617 rc = of_property_read_u32(core_node, "cy,vendor_id", &value);
618 if (!rc)
619 pdata->vendor_id = value;
620
621 rc = of_property_read_u32(core_node, "cy,product_id", &value);
622 if (!rc)
623 pdata->product_id = value;
624
625 rc = of_property_read_u32(core_node, "cy,flags", &value);
626 if (!rc)
627 pdata->flags = value;
628
629 rc = of_property_read_u32(core_node, "cy,easy_wakeup_gesture", &value);
630 if (!rc)
631 pdata->easy_wakeup_gesture = (u8)value;
632
633 for (i = 0; (unsigned int)i < ARRAY_SIZE(touch_setting_names); i++) {
634 if (touch_setting_names[i] == NULL)
635 continue;
636
637 pdata->sett[i] = create_and_get_touch_setting(core_node,
638 touch_setting_names[i]);
639 if (IS_ERR(pdata->sett[i])) {
640 rc = PTR_ERR(pdata->sett[i]);
641 goto fail_free_sett;
642 } else if (pdata->sett[i] == NULL)
643 pr_debug("%s: No data for setting '%s'\n", __func__,
644 touch_setting_names[i]);
645 }
646
647 pr_debug("%s: irq_gpio:%d rst_gpio:%d\n"
648 "hid_desc_register:%d level_irq_udelay:%d vendor_id:%d product_id:%d\n"
649 "flags:%d easy_wakeup_gesture:%d\n", __func__,
650 pdata->irq_gpio, pdata->rst_gpio,
651 pdata->hid_desc_register,
652 pdata->level_irq_udelay, pdata->vendor_id, pdata->product_id,
653 pdata->flags, pdata->easy_wakeup_gesture);
654
655 pdata->xres = cyttsp5_xres;
656 pdata->init = cyttsp5_init;
657 pdata->power = cyttsp5_power;
658 pdata->detect = cyttsp5_detect;
659 pdata->irq_stat = cyttsp5_irq_stat;
660
661 return pdata;
662
663 fail_free_sett:
664 for (i--; i >= 0; i--)
665 free_touch_setting(pdata->sett[i]);
666 fail_free:
667 kfree(pdata);
668 fail:
669 return ERR_PTR(rc);
670 }
671
free_core_pdata(void * pdata)672 static void free_core_pdata(void *pdata)
673 {
674 struct cyttsp5_core_platform_data *core_pdata = pdata;
675 unsigned int i;
676
677 for (i = 0; i < ARRAY_SIZE(touch_setting_names); i++)
678 free_touch_setting(core_pdata->sett[i]);
679 kfree(core_pdata);
680 }
681
cyttsp5_devtree_create_and_get_pdata(struct device * adap_dev)682 int cyttsp5_devtree_create_and_get_pdata(struct device *adap_dev)
683 {
684 struct cyttsp5_platform_data *pdata;
685 struct device_node *core_node, *dev_node, *dev_node_fail;
686 enum cyttsp5_device_type type;
687 int count = 0;
688 int rc = 0;
689
690 if (!adap_dev->of_node)
691 return 0;
692
693 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
694 if (!pdata)
695 return -ENOMEM;
696
697 adap_dev->platform_data = pdata;
698 set_pdata_ptr(pdata);
699
700 /* There should be only one core node */
701 for_each_child_of_node(adap_dev->of_node, core_node) {
702 const char *name;
703
704 rc = of_property_read_string(core_node, "name", &name);
705 if (!rc)
706 pr_debug("%s: name:%s\n", __func__, name);
707
708 pdata->core_pdata = create_and_get_core_pdata(core_node);
709 if (IS_ERR(pdata->core_pdata)) {
710 rc = PTR_ERR(pdata->core_pdata);
711 break;
712 }
713
714 /* Increment reference count */
715 of_node_get(core_node);
716
717 for_each_child_of_node(core_node, dev_node) {
718 count++;
719 rc = get_device_type(dev_node, &type);
720 if (rc)
721 break;
722 *pdata_ptr[type].pdata
723 = create_and_get_device_pdata(dev_node, type);
724 if (IS_ERR(*pdata_ptr[type].pdata))
725 rc = PTR_ERR(*pdata_ptr[type].pdata);
726 if (rc)
727 break;
728 /* Increment reference count */
729 of_node_get(dev_node);
730 }
731
732 if (rc) {
733 free_core_pdata(pdata->core_pdata);
734 of_node_put(core_node);
735 for_each_child_of_node(core_node, dev_node_fail) {
736 if (dev_node == dev_node_fail)
737 break;
738 rc = get_device_type(dev_node, &type);
739 if (rc)
740 break;
741 free_device_pdata(type);
742 of_node_put(dev_node);
743 }
744 break;
745 }
746 pdata->loader_pdata = &_cyttsp5_loader_platform_data;
747 }
748
749 pr_info("%s: %d child node(s) found\n", __func__, count);
750
751 return rc;
752 }
753 EXPORT_SYMBOL_GPL(cyttsp5_devtree_create_and_get_pdata);
754
cyttsp5_devtree_clean_pdata(struct device * adap_dev)755 int cyttsp5_devtree_clean_pdata(struct device *adap_dev)
756 {
757 struct cyttsp5_platform_data *pdata;
758 struct device_node *core_node, *dev_node;
759 enum cyttsp5_device_type type;
760 int rc = 0;
761
762 if (!adap_dev->of_node)
763 return 0;
764
765 pdata = dev_get_platdata(adap_dev);
766 set_pdata_ptr(pdata);
767 for_each_child_of_node(adap_dev->of_node, core_node) {
768 free_core_pdata(pdata->core_pdata);
769 of_node_put(core_node);
770 for_each_child_of_node(core_node, dev_node) {
771 rc = get_device_type(dev_node, &type);
772 if (rc)
773 break;
774 free_device_pdata(type);
775 of_node_put(dev_node);
776 }
777 }
778
779 return rc;
780 }
781 EXPORT_SYMBOL_GPL(cyttsp5_devtree_clean_pdata);
782
783 MODULE_LICENSE("GPL");
784 MODULE_DESCRIPTION("Parade TrueTouch(R) Standard Product DeviceTree Driver");
785 MODULE_AUTHOR("Parade Technologies <ttdrivers@paradetech.com>");
786