Lines Matching +full:max8997 +full:- +full:pmic

1 // SPDX-License-Identifier: GPL-2.0+
3 // extcon-max8997.c - MAX8997 extcon driver to support MAX8997 MUIC
8 #include <linux/devm-helpers.h>
17 #include <linux/mfd/max8997.h>
18 #include <linux/mfd/max8997-private.h>
19 #include <linux/extcon-provider.h>
22 #define DEV_NAME "max8997-muic"
39 { MAX8997_MUICIRQ_ADCError, "muic-ADCERROR" },
40 { MAX8997_MUICIRQ_ADCLow, "muic-ADCLOW" },
41 { MAX8997_MUICIRQ_ADC, "muic-ADC" },
42 { MAX8997_MUICIRQ_VBVolt, "muic-VBVOLT" },
43 { MAX8997_MUICIRQ_DBChg, "muic-DBCHG" },
44 { MAX8997_MUICIRQ_DCDTmr, "muic-DCDTMR" },
45 { MAX8997_MUICIRQ_ChgDetRun, "muic-CHGDETRUN" },
46 { MAX8997_MUICIRQ_ChgTyp, "muic-CHGTYP" },
47 { MAX8997_MUICIRQ_OVP, "muic-OVP" },
48 { MAX8997_PMICIRQ_CHGINS, "pmic-CHGINS" },
49 { MAX8997_PMICIRQ_CHGRM, "pmic-CHGRM" },
78 MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF, /* JIG-USB-OFF */
79 MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON, /* JIG-USB-ON */
82 MAX8997_MUIC_ADC_FACTORY_MODE_UART_OFF, /* JIG-UART */
156 * max8997_muic_set_debounce_time - Set the debounce time of ADC
157 * @info: the instance including private data of max8997 MUIC
170 ret = max8997_update_reg(info->muic, in max8997_muic_set_debounce_time()
175 dev_err(info->dev, "failed to set ADC debounce time\n"); in max8997_muic_set_debounce_time()
180 dev_err(info->dev, "invalid ADC debounce time\n"); in max8997_muic_set_debounce_time()
181 return -EINVAL; in max8997_muic_set_debounce_time()
188 * max8997_muic_set_path - Set hardware line according to attached cable
189 * @info: the instance including private data of max8997 MUIC
193 * The max8997 MUIC device share outside H/W line among a varity of cables,
208 ret = max8997_update_reg(info->muic, in max8997_muic_set_path()
211 dev_err(info->dev, "failed to update MUIC register\n"); in max8997_muic_set_path()
220 ret = max8997_update_reg(info->muic, in max8997_muic_set_path()
224 dev_err(info->dev, "failed to update MUIC register\n"); in max8997_muic_set_path()
228 dev_info(info->dev, in max8997_muic_set_path()
236 * max8997_muic_get_cable_type - Return cable type and check cable state
237 * @info: the instance including private data of max8997 MUIC
243 * - MAX8997_CABLE_GROUP_ADC
244 * - MAX8997_CABLE_GROUP_CHG
259 adc = info->status[0] & STATUS1_ADC_MASK; in max8997_muic_get_cable_type()
264 * (info->prev_cable_type) for handling cable when cable is in max8997_muic_get_cable_type()
270 cable_type = info->prev_cable_type; in max8997_muic_get_cable_type()
271 info->prev_cable_type = MAX8997_MUIC_ADC_OPEN; in max8997_muic_get_cable_type()
275 cable_type = info->prev_cable_type = adc; in max8997_muic_get_cable_type()
283 chg_type = info->status[1] & STATUS2_CHGTYP_MASK; in max8997_muic_get_cable_type()
289 cable_type = info->prev_chg_type; in max8997_muic_get_cable_type()
290 info->prev_chg_type = MAX8997_CHARGER_TYPE_NONE; in max8997_muic_get_cable_type()
296 * type(info->prev_chg_type) for handling cable when in max8997_muic_get_cable_type()
299 cable_type = info->prev_chg_type = chg_type; in max8997_muic_get_cable_type()
304 dev_err(info->dev, "Unknown cable group (%d)\n", group); in max8997_muic_get_cable_type()
305 cable_type = -EINVAL; in max8997_muic_get_cable_type()
317 ret = max8997_muic_set_path(info, info->path_usb, attached); in max8997_muic_handle_usb()
319 dev_err(info->dev, "failed to update muic register\n"); in max8997_muic_handle_usb()
325 extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached); in max8997_muic_handle_usb()
328 extcon_set_state_sync(info->edev, EXTCON_USB, attached); in max8997_muic_handle_usb()
329 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP, in max8997_muic_handle_usb()
333 dev_err(info->dev, "failed to detect %s usb cable\n", in max8997_muic_handle_usb()
335 return -EINVAL; in max8997_muic_handle_usb()
348 dev_err(info->dev, "failed to update muic register\n"); in max8997_muic_handle_dock()
355 extcon_set_state_sync(info->edev, EXTCON_DOCK, attached); in max8997_muic_handle_dock()
358 dev_err(info->dev, "failed to detect %s dock device\n", in max8997_muic_handle_dock()
360 return -EINVAL; in max8997_muic_handle_dock()
372 ret = max8997_muic_set_path(info, info->path_uart, attached); in max8997_muic_handle_jig_uart()
374 dev_err(info->dev, "failed to update muic register\n"); in max8997_muic_handle_jig_uart()
378 extcon_set_state_sync(info->edev, EXTCON_JIG, attached); in max8997_muic_handle_jig_uart()
400 extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached); in max8997_muic_adc_handler()
447 dev_info(info->dev, in max8997_muic_adc_handler()
450 return -EAGAIN; in max8997_muic_adc_handler()
452 dev_err(info->dev, in max8997_muic_adc_handler()
455 return -EINVAL; in max8997_muic_adc_handler()
474 adc = info->status[0] & STATUS1_ADC_MASK; in max8997_muic_chg_handler()
483 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP, in max8997_muic_chg_handler()
487 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP, in max8997_muic_chg_handler()
491 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW, in max8997_muic_chg_handler()
495 extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST, in max8997_muic_chg_handler()
499 dev_err(info->dev, in max8997_muic_chg_handler()
502 return -EINVAL; in max8997_muic_chg_handler()
515 if (!info->edev) in max8997_muic_irq_work()
518 mutex_lock(&info->mutex); in max8997_muic_irq_work()
521 if (info->irq == muic_irqs[i].virq) in max8997_muic_irq_work()
524 ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, in max8997_muic_irq_work()
525 2, info->status); in max8997_muic_irq_work()
527 dev_err(info->dev, "failed to read muic register\n"); in max8997_muic_irq_work()
528 mutex_unlock(&info->mutex); in max8997_muic_irq_work()
552 dev_info(info->dev, "misc interrupt: irq %d occurred\n", in max8997_muic_irq_work()
554 mutex_unlock(&info->mutex); in max8997_muic_irq_work()
559 dev_err(info->dev, "failed to handle MUIC interrupt\n"); in max8997_muic_irq_work()
561 mutex_unlock(&info->mutex); in max8997_muic_irq_work()
568 dev_dbg(info->dev, "irq:%d\n", irq); in max8997_muic_irq_handler()
569 info->irq = irq; in max8997_muic_irq_handler()
571 schedule_work(&info->irq_work); in max8997_muic_irq_handler()
583 mutex_lock(&info->mutex); in max8997_muic_detect_dev()
586 ret = max8997_bulk_read(info->muic, in max8997_muic_detect_dev()
587 MAX8997_MUIC_REG_STATUS1, 2, info->status); in max8997_muic_detect_dev()
589 dev_err(info->dev, "failed to read MUIC register\n"); in max8997_muic_detect_dev()
590 mutex_unlock(&info->mutex); in max8997_muic_detect_dev()
599 dev_err(info->dev, "Cannot detect ADC cable\n"); in max8997_muic_detect_dev()
600 mutex_unlock(&info->mutex); in max8997_muic_detect_dev()
610 dev_err(info->dev, "Cannot detect charger cable\n"); in max8997_muic_detect_dev()
611 mutex_unlock(&info->mutex); in max8997_muic_detect_dev()
616 mutex_unlock(&info->mutex); in max8997_muic_detect_dev()
629 dev_err(info->dev, "failed to detect cable type\n"); in max8997_muic_detect_cable_wq()
634 struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent); in max8997_muic_probe() local
635 struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev); in max8997_muic_probe()
642 info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info), in max8997_muic_probe()
645 return -ENOMEM; in max8997_muic_probe()
647 info->dev = &pdev->dev; in max8997_muic_probe()
648 info->muic = max8997->muic; in max8997_muic_probe()
651 mutex_init(&info->mutex); in max8997_muic_probe()
653 INIT_WORK(&info->irq_work, max8997_muic_irq_work); in max8997_muic_probe()
654 ret = devm_work_autocancel(&pdev->dev, &info->irq_work, in max8997_muic_probe()
663 virq = irq_create_mapping(max8997->irq_domain, muic_irq->irq); in max8997_muic_probe()
665 return -EINVAL; in max8997_muic_probe()
667 muic_irq->virq = virq; in max8997_muic_probe()
669 ret = devm_request_threaded_irq(&pdev->dev, virq, NULL, in max8997_muic_probe()
672 muic_irq->name, info); in max8997_muic_probe()
674 dev_err(&pdev->dev, in max8997_muic_probe()
676 muic_irq->irq, ret); in max8997_muic_probe()
682 info->edev = devm_extcon_dev_allocate(&pdev->dev, max8997_extcon_cable); in max8997_muic_probe()
683 if (IS_ERR(info->edev)) { in max8997_muic_probe()
684 dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); in max8997_muic_probe()
685 return PTR_ERR(info->edev); in max8997_muic_probe()
688 ret = devm_extcon_dev_register(&pdev->dev, info->edev); in max8997_muic_probe()
690 dev_err(&pdev->dev, "failed to register extcon device\n"); in max8997_muic_probe()
694 if (pdata && pdata->muic_pdata) { in max8997_muic_probe()
696 = pdata->muic_pdata; in max8997_muic_probe()
699 for (i = 0; i < muic_pdata->num_init_data; i++) { in max8997_muic_probe()
700 max8997_write_reg(info->muic, in max8997_muic_probe()
701 muic_pdata->init_data[i].addr, in max8997_muic_probe()
702 muic_pdata->init_data[i].data); in max8997_muic_probe()
709 if (muic_pdata->path_uart) in max8997_muic_probe()
710 info->path_uart = muic_pdata->path_uart; in max8997_muic_probe()
712 info->path_uart = CONTROL1_SW_UART; in max8997_muic_probe()
714 if (muic_pdata->path_usb) in max8997_muic_probe()
715 info->path_usb = muic_pdata->path_usb; in max8997_muic_probe()
717 info->path_usb = CONTROL1_SW_USB; in max8997_muic_probe()
723 if (muic_pdata->detcable_delay_ms) in max8997_muic_probe()
725 msecs_to_jiffies(muic_pdata->detcable_delay_ms); in max8997_muic_probe()
729 info->path_uart = CONTROL1_SW_UART; in max8997_muic_probe()
730 info->path_usb = CONTROL1_SW_USB; in max8997_muic_probe()
735 ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, in max8997_muic_probe()
736 2, info->status); in max8997_muic_probe()
738 dev_err(info->dev, "failed to read MUIC register\n"); in max8997_muic_probe()
744 max8997_muic_set_path(info, info->path_uart, true); in max8997_muic_probe()
752 * - Use delayed workqueue to detect cable state and then in max8997_muic_probe()
757 INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq); in max8997_muic_probe()
758 queue_delayed_work(system_power_efficient_wq, &info->wq_detcable, in max8997_muic_probe()
773 MODULE_DESCRIPTION("Maxim MAX8997 Extcon driver");
776 MODULE_ALIAS("platform:max8997-muic");