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;
}