static int palmas_gpio_to_irq(struct gpio_chip *gc, unsigned offset) { struct palmas_gpio *pg = gpiochip_get_data(gc); struct palmas *palmas = pg->palmas; return palmas_irq_get_virq(palmas, PALMAS_GPIO_0_IRQ + offset); }
static int palmas_usb_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct palmas_platform_data *pdata; struct palmas_extcon_platform_data *epdata = NULL; struct device_node *node = pdev->dev.of_node; struct palmas_usb *palmas_usb; int status; const char *ext_name = NULL; palmas_usb = devm_kzalloc(&pdev->dev, sizeof(*palmas_usb), GFP_KERNEL); if (!palmas_usb) return -ENOMEM; pdata = dev_get_platdata(pdev->dev.parent); if (pdata) epdata = pdata->extcon_pdata; if (node && !epdata) { palmas_usb->wakeup = of_property_read_bool(node, "ti,wakeup"); palmas_usb->enable_id_detection = of_property_read_bool(node, "ti,enable-id-detection"); palmas_usb->enable_vbus_detection = of_property_read_bool(node, "ti,enable-vbus-detection"); status = of_property_read_string(node, "extcon-name", &ext_name); if (status < 0) ext_name = NULL; } else { palmas_usb->wakeup = true; palmas_usb->enable_id_detection = true; palmas_usb->enable_vbus_detection = true; if (epdata) { palmas_usb->wakeup = epdata->wakeup; palmas_usb->enable_id_detection = epdata->enable_id_pin_detection; palmas_usb->enable_vbus_detection = epdata->enable_vbus_detection; if (palmas_usb->enable_id_detection) palmas_usb->wakeup = true; ext_name = epdata->connection_name; } } palmas_usb->palmas = palmas; palmas_usb->dev = &pdev->dev; palmas_usb->cable_debounce_time = 300; palmas_usb->id_otg_irq = palmas_irq_get_virq(palmas, PALMAS_ID_OTG_IRQ); palmas_usb->id_irq = palmas_irq_get_virq(palmas, PALMAS_ID_IRQ); palmas_usb->vbus_otg_irq = palmas_irq_get_virq(palmas, PALMAS_VBUS_OTG_IRQ); palmas_usb->vbus_irq = palmas_irq_get_virq(palmas, PALMAS_VBUS_IRQ); palmas_usb_wakeup(palmas, palmas_usb->wakeup); platform_set_drvdata(pdev, palmas_usb); palmas_usb->edev.supported_cable = palmas_extcon_cable; palmas_usb->edev.mutually_exclusive = mutually_exclusive; palmas_usb->edev.name = (ext_name) ? ext_name : dev_name(&pdev->dev); status = extcon_dev_register(&palmas_usb->edev, palmas_usb->dev); if (status < 0) { dev_err(&pdev->dev, "failed to register extcon device\n"); return status; } if (palmas_usb->enable_id_detection) { status = devm_request_threaded_irq(palmas_usb->dev, palmas_usb->id_irq, NULL, palmas_id_irq_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT | IRQF_EARLY_RESUME, "palmas_usb_id", palmas_usb); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", palmas_usb->id_irq, status); goto fail_extcon; } status = devm_request_threaded_irq(palmas_usb->dev, palmas_usb->id_otg_irq, NULL, palmas_id_irq_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT | IRQF_EARLY_RESUME, "palmas_usb_id-otg", palmas_usb); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", palmas_usb->id_irq, status); goto fail_extcon; } INIT_DELAYED_WORK(&palmas_usb->cable_update_wq, palmas_usb_id_st_wq); } if (palmas_usb->enable_vbus_detection) { status = devm_request_threaded_irq(palmas_usb->dev, palmas_usb->vbus_irq, NULL, palmas_vbus_irq_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT | IRQF_EARLY_RESUME, "palmas_usb_vbus", palmas_usb); if (status < 0) { dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", palmas_usb->vbus_irq, status); goto fail_extcon; } } palmas_enable_irq(palmas_usb); device_set_wakeup_capable(&pdev->dev, true); return 0; fail_extcon: extcon_dev_unregister(&palmas_usb->edev); if (palmas_usb->enable_id_detection) cancel_delayed_work(&palmas_usb->cable_update_wq); return status; }
static int palmas_gpadc_probe(struct platform_device *pdev) { struct palmas_gpadc *adc; struct palmas_platform_data *pdata; struct palmas_gpadc_platform_data *gpadc_pdata = NULL; struct iio_dev *iodev; int ret, i; pdata = dev_get_platdata(pdev->dev.parent); if (pdata && pdata->gpadc_pdata) gpadc_pdata = pdata->gpadc_pdata; if (!gpadc_pdata && pdev->dev.of_node) { ret = palmas_gpadc_get_adc_dt_data(pdev, &gpadc_pdata); if (ret < 0) return ret; } if (!gpadc_pdata) { dev_err(&pdev->dev, "No platform data\n"); return -ENODEV; } iodev = iio_device_alloc(sizeof(*adc)); if (!iodev) { dev_err(&pdev->dev, "iio_device_alloc failed\n"); return -ENOMEM; } if (gpadc_pdata->iio_maps) { ret = iio_map_array_register(iodev, gpadc_pdata->iio_maps); if (ret < 0) { dev_err(&pdev->dev, "iio_map_array_register failed\n"); goto out; } } adc = iio_priv(iodev); adc->dev = &pdev->dev; adc->palmas = dev_get_drvdata(pdev->dev.parent); adc->adc_info = palmas_gpadc_info; init_completion(&adc->conv_completion); dev_set_drvdata(&pdev->dev, iodev); adc->auto_conversion_period = gpadc_pdata->auto_conversion_period_ms; adc->irq = palmas_irq_get_virq(adc->palmas, PALMAS_GPADC_EOC_SW_IRQ); ret = request_threaded_irq(adc->irq, NULL, palmas_gpadc_irq, IRQF_ONESHOT | IRQF_EARLY_RESUME, dev_name(adc->dev), adc); if (ret < 0) { dev_err(adc->dev, "request irq %d failed: %dn", adc->irq, ret); goto out_unregister_map; } if (gpadc_pdata->adc_wakeup1_data) { memcpy(&adc->wakeup1_data, gpadc_pdata->adc_wakeup1_data, sizeof(adc->wakeup1_data)); adc->wakeup1_enable = true; adc->irq_auto_0 = platform_get_irq(pdev, 1); ret = request_threaded_irq(adc->irq_auto_0, NULL, palmas_gpadc_irq_auto, IRQF_ONESHOT | IRQF_EARLY_RESUME, "palmas-adc-auto-0", adc); if (ret < 0) { dev_err(adc->dev, "request auto0 irq %d failed: %dn", adc->irq_auto_0, ret); goto out_irq_free; } } if (gpadc_pdata->adc_wakeup2_data) { memcpy(&adc->wakeup2_data, gpadc_pdata->adc_wakeup2_data, sizeof(adc->wakeup2_data)); adc->wakeup2_enable = true; adc->irq_auto_1 = platform_get_irq(pdev, 2); ret = request_threaded_irq(adc->irq_auto_1, NULL, palmas_gpadc_irq_auto, IRQF_ONESHOT | IRQF_EARLY_RESUME, "palmas-adc-auto-1", adc); if (ret < 0) { dev_err(adc->dev, "request auto1 irq %d failed: %dn", adc->irq_auto_1, ret); goto out_irq_auto0_free; } } if (gpadc_pdata->ch0_current == 0) adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_0; else if (gpadc_pdata->ch0_current <= 5) adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_5; else if (gpadc_pdata->ch0_current <= 15) adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_15; else adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_20; if (gpadc_pdata->ch3_current == 0) adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_0; else if (gpadc_pdata->ch3_current <= 10) adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_10; else if (gpadc_pdata->ch3_current <= 400) adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_400; else adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_800; /* If ch3_dual_current is true, it will measure ch3 input signal with * ch3_current and the next current of ch3_current. */ adc->ch3_dual_current = gpadc_pdata->ch3_dual_current; if (adc->ch3_dual_current && (adc->ch3_current == PALMAS_ADC_CH3_CURRENT_SRC_800)) { dev_warn(adc->dev, "Disable ch3_dual_current by wrong current setting\n"); adc->ch3_dual_current = false; } adc->extended_delay = gpadc_pdata->extended_delay; iodev->name = MOD_NAME; iodev->dev.parent = &pdev->dev; iodev->info = &palmas_gpadc_iio_info; iodev->modes = INDIO_DIRECT_MODE; iodev->channels = palmas_gpadc_iio_channel; iodev->num_channels = ARRAY_SIZE(palmas_gpadc_iio_channel); ret = iio_device_register(iodev); if (ret < 0) { dev_err(adc->dev, "iio_device_register() failed: %d\n", ret); goto out_irq_auto1_free; } device_set_wakeup_capable(&pdev->dev, 1); for (i = 0; i < PALMAS_ADC_CH_MAX; i++) { if (!(adc->adc_info[i].is_correct_code)) palmas_gpadc_calibrate(adc, i); } if (adc->wakeup1_enable || adc->wakeup2_enable) device_wakeup_enable(&pdev->dev); return 0; out_irq_auto1_free: if (gpadc_pdata->adc_wakeup2_data) free_irq(adc->irq_auto_1, adc); out_irq_auto0_free: if (gpadc_pdata->adc_wakeup1_data) free_irq(adc->irq_auto_0, adc); out_irq_free: free_irq(adc->irq, adc); out_unregister_map: if (gpadc_pdata->iio_maps) iio_map_array_unregister(iodev); out: iio_device_free(iodev); return ret; }