static int max77843_muic_probe()

in extcon-max77843.c [810:930]


static int max77843_muic_probe(struct platform_device *pdev)
{
	struct max77693_dev *max77843 = dev_get_drvdata(pdev->dev.parent);
	struct max77843_muic_info *info;
	unsigned int id;
	int cable_type;
	bool attached;
	int i, ret;

	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->dev = &pdev->dev;
	info->max77843 = max77843;

	platform_set_drvdata(pdev, info);
	mutex_init(&info->mutex);

	/* Initialize i2c and regmap */
	ret = max77843_init_muic_regmap(max77843);
	if (ret) {
		dev_err(&pdev->dev, "Failed to init MUIC regmap\n");
		return ret;
	}

	/* Turn off auto detection configuration */
	ret = regmap_update_bits(max77843->regmap_muic,
			MAX77843_MUIC_REG_CONTROL4,
			MAX77843_MUIC_CONTROL4_USBAUTO_MASK |
			MAX77843_MUIC_CONTROL4_FCTAUTO_MASK,
			CONTROL4_AUTO_DISABLE);

	/* Initialize extcon device */
	info->edev = devm_extcon_dev_allocate(&pdev->dev,
			max77843_extcon_cable);
	if (IS_ERR(info->edev)) {
		dev_err(&pdev->dev, "Failed to allocate memory for extcon\n");
		ret = PTR_ERR(info->edev);
		goto err_muic_irq;
	}

	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register extcon device\n");
		goto err_muic_irq;
	}

	/* Set ADC debounce time */
	max77843_muic_set_debounce_time(info, MAX77843_DEBOUNCE_TIME_25MS);

	/* Set initial path for UART when JIG is connected to get serial logs */
	ret = regmap_bulk_read(max77843->regmap_muic,
			MAX77843_MUIC_REG_STATUS1, info->status,
			MAX77843_MUIC_STATUS_NUM);
	if (ret) {
		dev_err(info->dev, "Cannot read STATUS registers\n");
		goto err_muic_irq;
	}
	cable_type = max77843_muic_get_cable_type(info, MAX77843_CABLE_GROUP_ADC,
					 &attached);
	if (attached && cable_type == MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF)
		max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_UART,
				       true, false);

	/* Check revision number of MUIC device */
	ret = regmap_read(max77843->regmap_muic, MAX77843_MUIC_REG_ID, &id);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to read revision number\n");
		goto err_muic_irq;
	}
	dev_info(info->dev, "MUIC device ID : 0x%x\n", id);

	/* Support virtual irq domain for max77843 MUIC device */
	INIT_WORK(&info->irq_work, max77843_muic_irq_work);

	/* Clear IRQ bits before request IRQs */
	ret = regmap_bulk_read(max77843->regmap_muic,
			MAX77843_MUIC_REG_INT1, info->status,
			MAX77843_MUIC_STATUS_NUM);
	if (ret) {
		dev_err(&pdev->dev, "Failed to Clear IRQ bits\n");
		goto err_muic_irq;
	}

	for (i = 0; i < ARRAY_SIZE(max77843_muic_irqs); i++) {
		struct max77843_muic_irq *muic_irq = &max77843_muic_irqs[i];
		int virq = 0;

		virq = regmap_irq_get_virq(max77843->irq_data_muic,
				muic_irq->irq);
		if (virq <= 0) {
			ret = -EINVAL;
			goto err_muic_irq;
		}
		muic_irq->virq = virq;

		ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
				max77843_muic_irq_handler, IRQF_NO_SUSPEND,
				muic_irq->name, info);
		if (ret) {
			dev_err(&pdev->dev,
				"Failed to request irq (IRQ: %d, error: %d)\n",
				muic_irq->irq, ret);
			goto err_muic_irq;
		}
	}

	/* Detect accessory after completing the initialization of platform */
	INIT_DELAYED_WORK(&info->wq_detcable, max77843_muic_detect_cable_wq);
	queue_delayed_work(system_power_efficient_wq,
			&info->wq_detcable, msecs_to_jiffies(DELAY_MS_DEFAULT));

	return 0;

err_muic_irq:
	regmap_del_irq_chip(max77843->irq, max77843->irq_data_muic);
	i2c_unregister_device(max77843->i2c_muic);

	return ret;
}