Lines Matching full:cd

199 static bool goodix_berlin_is_dummy_data(struct goodix_berlin_core *cd,  in goodix_berlin_is_dummy_data()  argument
216 static int goodix_berlin_dev_confirm(struct goodix_berlin_core *cd) in goodix_berlin_dev_confirm() argument
224 error = regmap_raw_write(cd->regmap, in goodix_berlin_dev_confirm()
230 error = regmap_raw_read(cd->regmap, in goodix_berlin_dev_confirm()
242 dev_err(cd->dev, "device confirm failed, rx_buf: %*ph\n", in goodix_berlin_dev_confirm()
248 static int goodix_berlin_power_on(struct goodix_berlin_core *cd) in goodix_berlin_power_on() argument
252 error = regulator_enable(cd->vddio); in goodix_berlin_power_on()
254 dev_err(cd->dev, "Failed to enable vddio: %d\n", error); in goodix_berlin_power_on()
261 error = regulator_enable(cd->avdd); in goodix_berlin_power_on()
263 dev_err(cd->dev, "Failed to enable avdd: %d\n", error); in goodix_berlin_power_on()
270 gpiod_set_value_cansleep(cd->reset_gpio, 0); in goodix_berlin_power_on()
275 error = goodix_berlin_dev_confirm(cd); in goodix_berlin_power_on()
285 gpiod_set_value_cansleep(cd->reset_gpio, 1); in goodix_berlin_power_on()
286 regulator_disable(cd->avdd); in goodix_berlin_power_on()
288 regulator_disable(cd->vddio); in goodix_berlin_power_on()
292 static void goodix_berlin_power_off(struct goodix_berlin_core *cd) in goodix_berlin_power_off() argument
294 gpiod_set_value_cansleep(cd->reset_gpio, 1); in goodix_berlin_power_off()
295 regulator_disable(cd->avdd); in goodix_berlin_power_off()
296 regulator_disable(cd->vddio); in goodix_berlin_power_off()
299 static int goodix_berlin_read_version(struct goodix_berlin_core *cd) in goodix_berlin_read_version() argument
303 error = regmap_raw_read(cd->regmap, cd->ic_data->fw_version_info_addr, in goodix_berlin_read_version()
304 &cd->fw_version, sizeof(cd->fw_version)); in goodix_berlin_read_version()
306 dev_err(cd->dev, "error reading fw version, %d\n", error); in goodix_berlin_read_version()
310 if (!goodix_berlin_checksum_valid((u8 *)&cd->fw_version, in goodix_berlin_read_version()
311 sizeof(cd->fw_version))) { in goodix_berlin_read_version()
312 dev_err(cd->dev, "invalid fw version: checksum error\n"); in goodix_berlin_read_version()
320 static int goodix_berlin_parse_ic_info(struct goodix_berlin_core *cd, in goodix_berlin_parse_ic_info() argument
350 cd->touch_data_addr = le32_to_cpu(misc->touch_data_addr); in goodix_berlin_parse_ic_info()
355 dev_err(cd->dev, "ic_info length is invalid (offset %d length %d)\n", in goodix_berlin_parse_ic_info()
360 static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd) in goodix_berlin_get_ic_info() argument
371 error = regmap_raw_read(cd->regmap, cd->ic_data->ic_info_addr, in goodix_berlin_get_ic_info()
374 dev_err(cd->dev, "failed get ic info length, %d\n", error); in goodix_berlin_get_ic_info()
380 dev_err(cd->dev, "invalid ic info length %d\n", length); in goodix_berlin_get_ic_info()
384 error = regmap_raw_read(cd->regmap, cd->ic_data->ic_info_addr, afe_data, in goodix_berlin_get_ic_info()
387 dev_err(cd->dev, "failed get ic info data, %d\n", error); in goodix_berlin_get_ic_info()
392 if (goodix_berlin_is_dummy_data(cd, afe_data, length)) { in goodix_berlin_get_ic_info()
393 dev_err(cd->dev, "fw info data invalid\n"); in goodix_berlin_get_ic_info()
398 dev_err(cd->dev, "fw info checksum error\n"); in goodix_berlin_get_ic_info()
402 error = goodix_berlin_parse_ic_info(cd, afe_data, length); in goodix_berlin_get_ic_info()
407 if (!cd->touch_data_addr) { in goodix_berlin_get_ic_info()
408 dev_err(cd->dev, "touch_data_addr is null\n"); in goodix_berlin_get_ic_info()
415 static int goodix_berlin_get_remaining_contacts(struct goodix_berlin_core *cd, in goodix_berlin_get_remaining_contacts() argument
420 u32 addr = cd->touch_data_addr + GOODIX_BERLIN_HEADER_SIZE + offset; in goodix_berlin_get_remaining_contacts()
423 error = regmap_raw_read(cd->regmap, addr, in goodix_berlin_get_remaining_contacts()
424 &cd->event.data[offset], in goodix_berlin_get_remaining_contacts()
427 dev_err_ratelimited(cd->dev, "failed to get touch data, %d\n", in goodix_berlin_get_remaining_contacts()
435 static void goodix_berlin_report_state(struct goodix_berlin_core *cd, int n) in goodix_berlin_report_state() argument
438 (struct goodix_berlin_touch *)cd->event.data; in goodix_berlin_report_state()
449 dev_warn_once(cd->dev, "Stylus event type not handled\n"); in goodix_berlin_report_state()
455 dev_warn_ratelimited(cd->dev, "invalid finger id %d\n", id); in goodix_berlin_report_state()
459 input_mt_slot(cd->input_dev, id); in goodix_berlin_report_state()
460 input_mt_report_slot_state(cd->input_dev, MT_TOOL_FINGER, true); in goodix_berlin_report_state()
462 touchscreen_report_pos(cd->input_dev, &cd->props, in goodix_berlin_report_state()
465 input_report_abs(cd->input_dev, ABS_MT_TOUCH_MAJOR, in goodix_berlin_report_state()
469 input_mt_sync_frame(cd->input_dev); in goodix_berlin_report_state()
470 input_sync(cd->input_dev); in goodix_berlin_report_state()
473 static void goodix_berlin_touch_handler(struct goodix_berlin_core *cd) in goodix_berlin_touch_handler() argument
479 cd->event.hdr.request_type); in goodix_berlin_touch_handler()
481 dev_warn(cd->dev, "invalid touch num %d\n", touch_num); in goodix_berlin_touch_handler()
487 error = goodix_berlin_get_remaining_contacts(cd, touch_num); in goodix_berlin_touch_handler()
495 if (!goodix_berlin_checksum_valid(cd->event.data, len)) { in goodix_berlin_touch_handler()
496 dev_err(cd->dev, "touch data checksum error: %*ph\n", in goodix_berlin_touch_handler()
497 len, cd->event.data); in goodix_berlin_touch_handler()
502 goodix_berlin_report_state(cd, touch_num); in goodix_berlin_touch_handler()
505 static int goodix_berlin_request_handle_reset(struct goodix_berlin_core *cd) in goodix_berlin_request_handle_reset() argument
507 gpiod_set_value_cansleep(cd->reset_gpio, 1); in goodix_berlin_request_handle_reset()
509 gpiod_set_value_cansleep(cd->reset_gpio, 0); in goodix_berlin_request_handle_reset()
518 struct goodix_berlin_core *cd = data; in goodix_berlin_irq() local
556 error = regmap_raw_read(cd->regmap, cd->touch_data_addr, in goodix_berlin_irq()
557 &cd->event, in goodix_berlin_irq()
562 dev_warn_ratelimited(cd->dev, in goodix_berlin_irq()
567 if (cd->event.hdr.status == 0) in goodix_berlin_irq()
570 if (!goodix_berlin_checksum_valid((u8 *)&cd->event.hdr, in goodix_berlin_irq()
572 dev_warn_ratelimited(cd->dev, in goodix_berlin_irq()
575 &cd->event.hdr); in goodix_berlin_irq()
579 if (cd->event.hdr.status & GOODIX_BERLIN_TOUCH_EVENT) in goodix_berlin_irq()
580 goodix_berlin_touch_handler(cd); in goodix_berlin_irq()
582 if (cd->event.hdr.status & GOODIX_BERLIN_REQUEST_EVENT) { in goodix_berlin_irq()
583 switch (cd->event.hdr.request_type) { in goodix_berlin_irq()
585 if (cd->reset_gpio) in goodix_berlin_irq()
586 goodix_berlin_request_handle_reset(cd); in goodix_berlin_irq()
590 dev_warn(cd->dev, "unsupported request code 0x%x\n", in goodix_berlin_irq()
591 cd->event.hdr.request_type); in goodix_berlin_irq()
598 regmap_write(cd->regmap, cd->touch_data_addr, 0); in goodix_berlin_irq()
604 static int goodix_berlin_input_dev_config(struct goodix_berlin_core *cd, in goodix_berlin_input_dev_config() argument
610 input_dev = devm_input_allocate_device(cd->dev); in goodix_berlin_input_dev_config()
614 cd->input_dev = input_dev; in goodix_berlin_input_dev_config()
615 input_set_drvdata(input_dev, cd); in goodix_berlin_input_dev_config()
622 input_set_abs_params(cd->input_dev, ABS_MT_POSITION_X, in goodix_berlin_input_dev_config()
624 input_set_abs_params(cd->input_dev, ABS_MT_POSITION_Y, in goodix_berlin_input_dev_config()
626 input_set_abs_params(cd->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); in goodix_berlin_input_dev_config()
628 touchscreen_parse_properties(cd->input_dev, true, &cd->props); in goodix_berlin_input_dev_config()
630 error = input_mt_init_slots(cd->input_dev, GOODIX_BERLIN_MAX_TOUCH, in goodix_berlin_input_dev_config()
635 error = input_register_device(cd->input_dev); in goodix_berlin_input_dev_config()
644 struct goodix_berlin_core *cd = dev_get_drvdata(dev); in goodix_berlin_suspend() local
646 disable_irq(cd->irq); in goodix_berlin_suspend()
647 goodix_berlin_power_off(cd); in goodix_berlin_suspend()
654 struct goodix_berlin_core *cd = dev_get_drvdata(dev); in goodix_berlin_resume() local
657 error = goodix_berlin_power_on(cd); in goodix_berlin_resume()
661 enable_irq(cd->irq); in goodix_berlin_resume()
671 struct goodix_berlin_core *cd = data; in goodix_berlin_power_off_act() local
673 goodix_berlin_power_off(cd); in goodix_berlin_power_off_act()
681 struct goodix_berlin_core *cd = dev_get_drvdata(dev); in registers_read() local
684 error = regmap_raw_read(cd->regmap, off, buf, count); in registers_read()
694 struct goodix_berlin_core *cd = dev_get_drvdata(dev); in registers_write() local
697 error = regmap_raw_write(cd->regmap, off, buf, count); in registers_write()
723 struct goodix_berlin_core *cd; in goodix_berlin_probe() local
731 cd = devm_kzalloc(dev, sizeof(*cd), GFP_KERNEL); in goodix_berlin_probe()
732 if (!cd) in goodix_berlin_probe()
735 cd->dev = dev; in goodix_berlin_probe()
736 cd->regmap = regmap; in goodix_berlin_probe()
737 cd->irq = irq; in goodix_berlin_probe()
738 cd->ic_data = ic_data; in goodix_berlin_probe()
740 cd->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); in goodix_berlin_probe()
741 if (IS_ERR(cd->reset_gpio)) in goodix_berlin_probe()
742 return dev_err_probe(dev, PTR_ERR(cd->reset_gpio), in goodix_berlin_probe()
745 cd->avdd = devm_regulator_get(dev, "avdd"); in goodix_berlin_probe()
746 if (IS_ERR(cd->avdd)) in goodix_berlin_probe()
747 return dev_err_probe(dev, PTR_ERR(cd->avdd), in goodix_berlin_probe()
750 cd->vddio = devm_regulator_get(dev, "vddio"); in goodix_berlin_probe()
751 if (IS_ERR(cd->vddio)) in goodix_berlin_probe()
752 return dev_err_probe(dev, PTR_ERR(cd->vddio), in goodix_berlin_probe()
755 error = goodix_berlin_power_on(cd); in goodix_berlin_probe()
761 error = devm_add_action_or_reset(dev, goodix_berlin_power_off_act, cd); in goodix_berlin_probe()
765 error = goodix_berlin_read_version(cd); in goodix_berlin_probe()
771 error = goodix_berlin_get_ic_info(cd); in goodix_berlin_probe()
777 error = goodix_berlin_input_dev_config(cd, id); in goodix_berlin_probe()
783 error = devm_request_threaded_irq(dev, cd->irq, NULL, goodix_berlin_irq, in goodix_berlin_probe()
784 IRQF_ONESHOT, "goodix-berlin", cd); in goodix_berlin_probe()
790 dev_set_drvdata(dev, cd); in goodix_berlin_probe()
793 cd->fw_version.patch_pid); in goodix_berlin_probe()