static int __devinit crystalcove_gpadc_probe(struct platform_device *pdev) { int err; struct gpadc_info *info; struct iio_dev *indio_dev; intel_mid_pmic_writeb(MADCIRQ0, 0x00); intel_mid_pmic_writeb(MADCIRQ1, 0x00); indio_dev = iio_allocate_device(sizeof(struct gpadc_info)); if (indio_dev == NULL) { dev_err(&pdev->dev, "allocating iio device failed\n"); return -ENOMEM; } info = iio_priv(indio_dev); mutex_init(&info->lock); init_waitqueue_head(&info->wait); info->dev = &pdev->dev; info->irq = platform_get_irq(pdev, 0); err = request_threaded_irq(info->irq, NULL, gpadc_isr, IRQF_ONESHOT, "adc", indio_dev); if (err) { dev_err(&pdev->dev, "unable to register irq %d\n", info->irq); goto err_free_device; } platform_set_drvdata(pdev, indio_dev); indio_dev->dev.parent = &pdev->dev; indio_dev->name = pdev->name; indio_dev->channels = crystalcove_adc_channels; indio_dev->num_channels = ARRAY_SIZE(crystalcove_adc_channels); indio_dev->info = &crystalcove_adc_info; indio_dev->modes = INDIO_DIRECT_MODE; err = iio_map_array_register(indio_dev, iio_maps); if (err) goto err_release_irq; err = iio_device_register(indio_dev); if (err < 0) goto err_array_unregister; dev_info(&pdev->dev, "crystalcove adc probed\n"); return 0; err_array_unregister: iio_map_array_unregister(indio_dev, iio_maps); err_release_irq: free_irq(info->irq, info); err_free_device: iio_free_device(indio_dev); return err; }
static int __devexit crystalcove_gpadc_remove(struct platform_device *pdev) { struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct gpadc_info *info = iio_priv(indio_dev); iio_device_unregister(indio_dev); iio_map_array_unregister(indio_dev, iio_maps); free_irq(info->irq, info); iio_free_device(indio_dev); return 0; }
static int bcove_gpadc_remove(struct platform_device *pdev) { struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct gpadc_info *info = iio_priv(indio_dev); sysfs_remove_group(&pdev->dev.kobj, &intel_basincove_gpadc_attr_group); iio_device_unregister(indio_dev); iio_map_array_unregister(indio_dev); free_irq(info->irq, info); iounmap(info->intr); iio_device_free(indio_dev); return 0; }
static int palmas_gpadc_remove(struct platform_device *pdev) { struct iio_dev *iodev = dev_to_iio_dev(&pdev->dev); struct palmas_gpadc *adc = iio_priv(iodev); struct palmas_platform_data *pdata = dev_get_platdata(pdev->dev.parent); if (pdata->gpadc_pdata->iio_maps) iio_map_array_unregister(iodev); iio_device_unregister(iodev); free_irq(adc->irq, adc); if (adc->wakeup1_enable) free_irq(adc->irq_auto_0, adc); if (adc->wakeup2_enable) free_irq(adc->irq_auto_1, adc); iio_device_free(iodev); return 0; }
static int bcove_gpadc_probe(struct platform_device *pdev) { int err; struct gpadc_info *info; struct iio_dev *indio_dev; struct intel_basincove_gpadc_platform_data *pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data supplied\n"); err = -EINVAL; goto out; } indio_dev = iio_device_alloc(sizeof(struct gpadc_info)); if (indio_dev == NULL) { dev_err(&pdev->dev, "allocating iio device failed\n"); err = -ENOMEM; goto out; } info = iio_priv(indio_dev); mutex_init(&info->lock); init_waitqueue_head(&info->wait); info->dev = &pdev->dev; info->irq = platform_get_irq(pdev, 0); info->intr = ioremap_nocache(pdata->intr, 1); if (!info->intr) { dev_err(&pdev->dev, "ioremap of ADCIRQ failed\n"); err = -ENOMEM; goto err_free; } info->intr_mask = pdata->intr_mask; info->channel_num = pdata->channel_num; info->gpadc_regmaps = pdata->gpadc_regmaps; info->gpadc_regs = pdata->gpadc_regs; err = request_threaded_irq(info->irq, gpadc_isr, gpadc_threaded_isr, IRQF_ONESHOT, "adc", indio_dev); if (err) { gpadc_dump(info); dev_err(&pdev->dev, "unable to register irq %d\n", info->irq); goto err_iounmap; } platform_set_drvdata(pdev, indio_dev); indio_dev->dev.parent = &pdev->dev; indio_dev->name = pdev->name; indio_dev->channels = pdata->gpadc_channels; indio_dev->num_channels = pdata->channel_num; indio_dev->info = &basincove_adc_info; indio_dev->modes = INDIO_DIRECT_MODE; err = iio_map_array_register(indio_dev, pdata->gpadc_iio_maps); if (err) goto err_release_irq; err = iio_device_register(indio_dev); if (err < 0) goto err_array_unregister; err = sysfs_create_group(&pdev->dev.kobj, &intel_basincove_gpadc_attr_group); if (err) { dev_err(&pdev->dev, "Unable to export sysfs interface, error: %d\n", err); goto err_iio_device_unregister; } info->initialized = 1; dev_info(&pdev->dev, "bcove adc probed\n"); return 0; err_iio_device_unregister: iio_device_unregister(indio_dev); err_array_unregister: iio_map_array_unregister(indio_dev); err_release_irq: free_irq(info->irq, info); err_iounmap: iounmap(info->intr); err_free: iio_device_free(indio_dev); out: return err; }
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; }