Exemplo n.º 1
0
static int tiadc_channel_init(struct iio_dev *indio_dev,
		struct tiadc_device *adc_dev)
{
	struct iio_chan_spec *chan_array;
	struct iio_chan_spec *chan;
	char *s;
	int i, len, size, ret;
	int channels = adc_dev->channels;

	size = channels * (sizeof(struct iio_chan_spec) + 6);
	chan_array = kzalloc(size, GFP_KERNEL);
	if (chan_array == NULL)
		return -ENOMEM;

	/* buffer space is after the array */
	s = (char *)(chan_array + channels);
	chan = chan_array;
	for (i = 0; i < channels; i++, chan++, s += len + 1) {

		len = sprintf(s, "AIN%d", i);

		chan->type = IIO_VOLTAGE;
		chan->indexed = 1;
		chan->channel = i;
		chan->datasheet_name = s;
		chan->scan_type.sign = 'u';
		chan->scan_type.realbits = 12;
		chan->scan_type.storagebits = 32;
		chan->scan_type.shift = 0;
	}

	indio_dev->channels = chan_array;
	indio_dev->num_channels = channels;

	size = (channels + 1) * sizeof(struct iio_map);
	adc_dev->map = kzalloc(size, GFP_KERNEL);
	if (adc_dev->map == NULL) {
		kfree(chan_array);
		return -ENOMEM;
	}

	for (i = 0; i < indio_dev->num_channels; i++) {
		adc_dev->map[i].adc_channel_label = chan_array[i].datasheet_name;
		adc_dev->map[i].consumer_dev_name = "any";
		adc_dev->map[i].consumer_channel = chan_array[i].datasheet_name;
	}
	adc_dev->map[i].adc_channel_label = NULL;
	adc_dev->map[i].consumer_dev_name = NULL;
	adc_dev->map[i].consumer_channel = NULL;

	ret = iio_map_array_register(indio_dev, adc_dev->map);
	if (ret != 0) {
		kfree(adc_dev->map);
		kfree(chan_array);
		return -ENOMEM;
	}

	return indio_dev->num_channels;
}
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 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;
}
Exemplo n.º 4
0
static int __devinit max77660_adc_probe(struct platform_device *pdev)
{
	struct max77660_adc *adc;
	struct max77660_platform_data *pdata;
	struct max77660_adc_platform_data *adc_pdata;
	struct iio_dev *iodev;
	int ret;

	pdata = dev_get_platdata(pdev->dev.parent);
	if (!pdata || !pdata->adc_pdata) {
		dev_err(&pdev->dev, "No platform data\n");
		return -ENODEV;
	}
	adc_pdata = pdata->adc_pdata;

	iodev = iio_allocate_device(sizeof(*adc));
	if (!iodev) {
		dev_err(&pdev->dev, "iio_device_alloc failed\n");
		return -ENOMEM;
	}
	adc = iio_priv(iodev);
	adc->dev = &pdev->dev;
	adc->parent = pdev->dev.parent;
	adc->adc_info = max77660_adc_info;
	init_completion(&adc->conv_completion);
	dev_set_drvdata(&pdev->dev, iodev);

	adc->irq = platform_get_irq(pdev, 0);
	ret = request_threaded_irq(adc->irq, NULL,
		max77660_adc_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;
	}

	if (adc_pdata->adc_ref_enabled)
		adc->adc_control |= MAX77660_ADCCTRL_ADCREFEN;

	if (adc_pdata->adc_avg_sample <= 1)
		adc->adc_control |= MAX77660_ADCCTRL_ADCAVG(0);
	else if (adc_pdata->adc_avg_sample <= 2)
		adc->adc_control |= MAX77660_ADCCTRL_ADCAVG(1);
	else if (adc_pdata->adc_avg_sample <= 16)
		adc->adc_control |= MAX77660_ADCCTRL_ADCAVG(2);
	else
		adc->adc_control |= MAX77660_ADCCTRL_ADCAVG(3);

	if (adc_pdata->adc_current_uA == 0)
		adc->iadc_val = 0;
	else if (adc_pdata->adc_current_uA <= 10)
		adc->iadc_val = 1;
	else if (adc_pdata->adc_current_uA <= 50)
		adc->iadc_val = 2;
	else
		adc->iadc_val = 3;

	iodev->name = MOD_NAME;
	iodev->dev.parent = &pdev->dev;
	iodev->info = &max77660_adc_iio_info;
	iodev->modes = INDIO_DIRECT_MODE;
	iodev->channels = max77660_adc_iio_channel;
	iodev->num_channels = ARRAY_SIZE(max77660_adc_iio_channel);
	ret = iio_device_register(iodev);
	if (ret < 0) {
		dev_err(adc->dev, "iio_device_register() failed: %d\n", ret);
		goto out_irq_free;
	}

	if (adc_pdata->channel_mapping) {
		ret = iio_map_array_register(iodev, adc_pdata->channel_mapping);
		if (ret < 0) {
			dev_err(adc->dev,
				"iio_map_array_register() failed: %d\n", ret);
			goto out_irq_free;
			}
	}

	device_set_wakeup_capable(&pdev->dev, 1);
	if (adc_pdata->adc_wakeup_data) {
		memcpy(&adc->adc_wake_props, adc_pdata->adc_wakeup_data,
			sizeof(struct max77660_adc_wakeup_property));
		adc->wakeup_props_available = true;
		device_wakeup_enable(&pdev->dev);
	}
	return 0;

out_irq_free:
	free_irq(adc->irq, adc);
out:
	iio_free_device(iodev);
	return ret;
}
Exemplo n.º 5
0
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;
}