Пример #1
0
static int gp2a_i2c_remove(struct i2c_client *client)
{
	struct gp2a_data *gp2a = i2c_get_clientdata(client);
	sysfs_remove_group(&gp2a->light_input_dev->dev.kobj,
			&light_attribute_group);
	input_unregister_device(gp2a->light_input_dev);
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			&proximity_attribute_group);
	input_unregister_device(gp2a->proximity_input_dev);

	platform_device_unregister(pdev_gp2a_adc);
	free_irq(gp2a->irq, NULL);
	gpio_free(gp2a->pdata->p_out);
	if (gp2a->power_state) {
		if (gp2a->power_state & LIGHT_ENABLED)
			gp2a_light_disable(gp2a);
		/* gp2a->pdata->power(false); */
	}

	destroy_workqueue(gp2a->wq);
	mutex_destroy(&gp2a->power_mutex);
	mutex_destroy(&gp2a->adc_mutex);

	wake_lock_destroy(&gp2a->prx_wake_lock);
	s3c_adc_release(gp2a->padc);
	kfree(gp2a);
	return 0;
}
Пример #2
0
static int __devexit exynos_adc_remove(struct platform_device *dev)
{
	misc_deregister(&misc);
	s3c_adc_release(adcdev.client);

	return 0;
}
void remove_temphumidity_factorytest(struct ssp_data *data)
{
	if (data->adc_client)
		s3c_adc_release(data->adc_client);
	if (data->pdev_pam_temp)
		platform_device_put(data->pdev_pam_temp);
	sensors_unregister(data->temphumidity_device, temphumidity_attrs);
	kfree(data->comp_engine_ver);
	ssp_temphumidity_fops.unlocked_ioctl = NULL;
	misc_deregister(&data->shtc1_device);
}
Пример #4
0
static int __devexit s3c_hwmon_remove(struct platform_device *dev)
{
    struct s3c_hwmon *hwmon = platform_get_drvdata(dev);
    int i;

    s3c_hwmon_remove_raw(&dev->dev);

    for (i = 0; i < ARRAY_SIZE(hwmon->attrs); i++)
        s3c_hwmon_remove_attr(&dev->dev, &hwmon->attrs[i]);

    hwmon_device_unregister(hwmon->hwmon_dev);
    s3c_adc_release(hwmon->client);

    return 0;
}
Пример #5
0
static int __devexit sec_therm_remove(struct platform_device *pdev)
{
	struct sec_therm_info *info = platform_get_drvdata(pdev);

	if (!info)
		return 0;

	sysfs_remove_group(&info->dev->kobj, &sec_therm_group);

	cancel_delayed_work(&info->polling_work);
	s3c_adc_release(info->padc);
	kfree(info);

	return 0;
}
Пример #6
0
static int  fl2440adc_release(struct inode *inodp, struct file *filp)
{
    int channel;

    DPRINTK("File operations release...\n");
    channel = MINOR(inodp->i_rdev);
    mutex_lock(&adc_dev.mutex);

    if(!(atomic_add_unless(&adc_dev.client_ref[channel], -1, 0)))
    {
        s3c_adc_release(adc_dev.client[channel]);
        adc_dev.client[channel] = NULL;
    }
    mutex_unlock(&adc_dev.mutex);

    return 0;
}
Пример #7
0
static int instinctq_battery_remove(struct platform_device *pdev)
{
	struct instinctq_battery *bat = platform_get_drvdata(pdev);
	struct instinctq_battery_pdata *pdata = bat->pdata;
	int i;

	disable_irq_wake(bat->irq_pok);

	free_irq(IRQ_BATF, bat);
	free_irq(bat->irq_pok, bat);

	if (pdata->supply_detect_cleanup)
		pdata->supply_detect_cleanup();

	for (i = 0; i < ARRAY_SIZE(battery_attrs); ++i)
		device_remove_file(bat->bat.dev, battery_attrs[i]);
	power_supply_unregister(&bat->bat);
#ifdef CONFIG_HAS_WAKELOCK
	device_remove_file(bat->psy[instinctq_BATTERY_AC].dev,
							&dev_attr_suspend_lock);
#endif
	for (i = 0; i < instinctq_BATTERY_NUM; ++i)
		power_supply_unregister(&bat->psy[i]);

	cancel_work_sync(&bat->work);
	cancel_delayed_work_sync(&bat->poll_work);
	destroy_workqueue(bat->workqueue);

	s3c_adc_release(bat->client);

	kfree(bat->temp_lookup.table);
	kfree(bat->volt_lookup.table);
	kfree(bat->percent_lookup.table);

	gpio_set_value(pdata->gpio_en, pdata->gpio_en_inverted);
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_destroy(&bat->fault_wakelock);
	wake_lock_destroy(&bat->chg_wakelock);
	wake_lock_destroy(&bat->wakelock);
	wake_lock_destroy(&bat->suspend_lock);
#endif
	kfree(bat);

	return 0;
}
static int s3c_adc_bat_remove(struct platform_device *pdev)
{
	struct s3c_adc_client *client = platform_get_drvdata(pdev);
	struct s3c_adc_bat_pdata *pdata = pdev->dev.platform_data;

	power_supply_unregister(&main_bat.psy);
	if (pdata->backup_volt_mult)
		power_supply_unregister(&backup_bat.psy);

	s3c_adc_release(client);

	if (pdata->gpio_charge_finished >= 0) {
		free_irq(gpio_to_irq(pdata->gpio_charge_finished), NULL);
		gpio_free(pdata->gpio_charge_finished);
	}

	cancel_delayed_work(&bat_work);

	if (pdata->exit)
		pdata->exit();

	return 0;
}
Пример #9
0
static int __devexit gpio_switch_remove(struct platform_device *pdev)
{
	struct gpio_switch_data *switch_data = platform_get_drvdata(pdev);

	if (is_adc_timer_on)
		del_timer(&detect_mic_adc_timer);
	cancel_delayed_work_sync(&switch_data->del_work);
	cancel_work_sync(&mic_adc_work);

	input_unregister_device(mic_input_dev);

	gpio_free(switch_data->gpio);
	switch_dev_unregister(&switch_data->sdev);
	kfree(switch_data);

	gpio_free(switch_data->gpio);
	switch_dev_unregister(&switch_data->sdev);
	kfree(switch_data);

	s3c_adc_release(switch_data->client);

	return 0;
}
Пример #10
0
static int instinctq_battery_probe(struct platform_device *pdev)
{
	struct s3c_adc_client	*client;
	struct instinctq_battery_pdata *pdata = pdev->dev.platform_data;
	struct instinctq_battery *bat;
	int ret, i, irq;

	/* Platform data is required */
	if (!pdata) {
		dev_err(&pdev->dev, "no platform data supplied\n");
		return -ENODEV;
	}

	/* Check GPIOs */
	if (!gpio_is_valid(pdata->gpio_pok)) {
		dev_err(&pdev->dev, "Invalid gpio pin for POK line\n");
		return -EINVAL;
	}

	if (!gpio_is_valid(pdata->gpio_chg)) {
		dev_err(&pdev->dev, "Invalid gpio pin for CHG line\n");
		return -EINVAL;
	}

	if (!gpio_is_valid(pdata->gpio_en)) {
		dev_err(&pdev->dev, "Invalid gpio pin for EN line\n");
		return -EINVAL;
	}

	if (!pdata->supply_detect_init) {
		dev_err(&pdev->dev, "Supply detection is required\n");
		return -EINVAL;
	}

	/* Register ADC client */
	client = s3c_adc_register(pdev, NULL, NULL, 0);
	if (IS_ERR(client)) {
		dev_err(&pdev->dev, "could not register adc\n");
		return PTR_ERR(client);
	}

	/* Allocate driver data */
	bat = kzalloc(sizeof(struct instinctq_battery), GFP_KERNEL);
	if (!bat) {
		dev_err(&pdev->dev, "could not allocate driver data\n");
		ret = -ENOMEM;
		goto err_free_adc;
	}

	/* Claim and setup GPIOs */
	ret = gpio_request(pdata->gpio_pok, dev_name(&pdev->dev));
	if (ret) {
		dev_err(&pdev->dev, "Failed to request POK pin: %d\n", ret);
		goto err_free;
	}

	ret = gpio_direction_input(pdata->gpio_pok);
	if (ret) {
		dev_err(&pdev->dev, "Failed to set POK to input: %d\n", ret);
		goto err_gpio_pok_free;
	}

	ret = gpio_request(pdata->gpio_chg, dev_name(&pdev->dev));
	if (ret) {
		dev_err(&pdev->dev, "Failed to request CHG pin: %d\n", ret);
		goto err_gpio_pok_free;
	}

	ret = gpio_direction_input(pdata->gpio_chg);
	if (ret) {
		dev_err(&pdev->dev, "Failed to set CHG to input: %d\n", ret);
		goto err_gpio_chg_free;
	}

	ret = gpio_request(pdata->gpio_en, dev_name(&pdev->dev));
	if (ret) {
		dev_err(&pdev->dev, "Failed to request EN pin: %d\n", ret);
		goto err_gpio_chg_free;
	}

	ret = gpio_direction_output(pdata->gpio_en, pdata->gpio_en_inverted);
	if (ret) {
		dev_err(&pdev->dev, "Failed to set EN to output: %d\n", ret);
		goto err_gpio_en_free;
	}

	platform_set_drvdata(pdev, bat);

	bat->dev = &pdev->dev;
	bat->client = client;
	bat->pdata = pdata;
	bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
	bat->health = POWER_SUPPLY_HEALTH_GOOD;
	bat->supply = instinctq_BATTERY_NONE;
	bat->interval = BAT_POLL_INTERVAL;
	bat->calibration = pdata->calibration;

	ret = create_lookup_table(pdata->percent_lut,
				pdata->percent_lut_cnt, &bat->percent_lookup);
	if (ret) {
		dev_err(&pdev->dev, "could not get create percentage lookup table");
		goto err_gpio_en_free;
	}

	ret = create_lookup_table(pdata->volt_lut,
				pdata->volt_lut_cnt, &bat->volt_lookup);
	if (ret) {
		dev_err(&pdev->dev, "could not get create voltage lookup table");
		goto err_percent_free;
	}

	ret = create_lookup_table(pdata->temp_lut,
				pdata->temp_lut_cnt, &bat->temp_lookup);
	if (ret) {
		dev_err(&pdev->dev, "could not get create temperature lookup table");
		goto err_volt_free;
	}

	INIT_WORK(&bat->work, instinctq_battery_work);
	INIT_DELAYED_WORK(&bat->poll_work, instinctq_battery_poll);
	mutex_init(&bat->mutex);
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_init(&bat->wakelock, WAKE_LOCK_SUSPEND, "battery");
	wake_lock_init(&bat->chg_wakelock, WAKE_LOCK_SUSPEND, "charger");
	wake_lock_init(&bat->fault_wakelock,
					WAKE_LOCK_SUSPEND, "battery fault");
	wake_lock_init(&bat->suspend_lock, WAKE_LOCK_SUSPEND, "suspend_lock");
#endif
#ifdef CONFIG_RTC_INTF_ALARM
	alarm_init(&bat->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
							instinctq_battery_alarm);
#endif
	/* Get some initial data for averaging */
	for (i = 0; i < NUM_SAMPLES; ++i) {
		int sample;
		/* Get a voltage sample from the ADC */
		sample = instinctq_battery_adc_read(bat->client, bat->pdata->volt_channel);
		if (sample < 0) {
			dev_warn(&pdev->dev, "Failed to get ADC sample.\n");
			continue;
		}
		sample += bat->compensation;
		bat->vol_adc = sample;
		/* Put the sample and get the new average */
		bat->volt_value = put_sample_get_avg(&bat->volt_avg, sample);
		/* Get a temperature sample from the ADC */
		sample = instinctq_battery_adc_read(bat->client, bat->pdata->temp_channel);
		if (sample < 0) {
			dev_warn(&pdev->dev, "Failed to get ADC sample.\n");
			continue;
		}
		bat->temp_adc = sample;
		/* Put the sample and get the new average */
		bat->temp_value = put_sample_get_avg(&bat->temp_avg, sample);
	}

	bat->percent_value = lookup_value(&bat->percent_lookup, bat->volt_value);
	bat->volt_value = lookup_value(&bat->volt_lookup, bat->volt_value);
	bat->temp_value = lookup_value(&bat->temp_lookup, bat->temp_value);
	bat->last_sample = ktime_get_boottime();

	/* Register the power supplies */
	for (i = 0; i < instinctq_BATTERY_NUM; ++i) {
		bat->psy[i] = instinctq_chg_templates[i];
		ret = power_supply_register(&pdev->dev, &bat->psy[i]);
		if (ret < 0) {
			dev_err(&pdev->dev,
				"Failed to register power supply %s (%d)\n",
							bat->psy[i].name, ret);
			break;
		}
	}

	/* Undo the loop on error */
	if (i-- != instinctq_BATTERY_NUM) {
		for (; i >= 0; --i)
			power_supply_unregister(&bat->psy[i]);
		goto err_temp_free;
	}
#ifdef CONFIG_HAS_WAKELOCK
	ret = device_create_file(bat->psy[instinctq_BATTERY_AC].dev,
							&dev_attr_suspend_lock);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"Failed to register device attribute.\n");
		goto err_psy_unreg;
	}
#endif
	/* Register the battery */
	bat->bat = instinctq_bat_template;
	ret = power_supply_register(&pdev->dev, &bat->bat);
	if (ret < 0) {
		dev_err(&pdev->dev,
			"Failed to register battery power supply: %d\n", ret);
		goto err_attr_unreg;
	}

	for (i = 0; i < ARRAY_SIZE(battery_attrs); ++i) {
		ret = device_create_file(bat->bat.dev, battery_attrs[i]);
		if (ret < 0)
			break;
	}

	if (ret < 0) {
		for (; i >= 0; --i)
			device_remove_file(bat->bat.dev, battery_attrs[i]);
		goto err_bat_unreg;
	}

	bat->workqueue = create_freezable_workqueue(dev_name(&pdev->dev));
	if (!bat->workqueue) {
		dev_err(&pdev->dev, "Failed to create freezeable workqueue\n");
		ret = -ENOMEM;
		goto err_remove_bat_attr;
	}

	/* Claim IRQs */
	irq = gpio_to_irq(pdata->gpio_pok);
	if (irq <= 0) {
		dev_err(&pdev->dev, "POK irq invalid.\n");
		goto err_destroy_workqueue;
	}
	bat->irq_pok = irq;

	ret = request_irq(irq, instinctq_charger_irq,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				dev_name(&pdev->dev), bat);
	if (ret) {
		dev_err(&pdev->dev, "Failed to request POK irq (%d)\n", ret);
		goto err_destroy_workqueue;
	}

	ret = request_irq(IRQ_BATF, instinctq_battery_fault_irq,
						0, dev_name(&pdev->dev), bat);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed to request battery fault irq (%d)\n", ret);
		goto err_pok_irq_free;
	}

	enable_irq_wake(bat->irq_pok);

	instinctq_battery_set_fault_enable(1);

	/* Finish */
	dev_info(&pdev->dev, "successfully loaded\n");
	device_init_wakeup(&pdev->dev, 1);

	pdata->supply_detect_init(instinctq_battery_supply_notify);

	/* Schedule work to check current status */
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock(&bat->wakelock);
#endif
	queue_work(bat->workqueue, &bat->work);

	return 0;

err_pok_irq_free:
	free_irq(bat->irq_pok, bat);
err_destroy_workqueue:
	destroy_workqueue(bat->workqueue);
err_remove_bat_attr:
	for (i = 0; i < ARRAY_SIZE(battery_attrs); ++i)
		device_remove_file(bat->bat.dev, battery_attrs[i]);
err_bat_unreg:
	power_supply_unregister(&bat->bat);
err_attr_unreg:
#ifdef CONFIG_HAS_WAKELOCK
	device_remove_file(bat->psy[instinctq_BATTERY_AC].dev,
							&dev_attr_suspend_lock);
err_psy_unreg:
#endif
	for (i = 0; i < instinctq_BATTERY_NUM; ++i)
		power_supply_unregister(&bat->psy[i]);
err_temp_free:
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_destroy(&bat->wakelock);
	wake_lock_destroy(&bat->chg_wakelock);
	wake_lock_destroy(&bat->fault_wakelock);
	wake_lock_destroy(&bat->suspend_lock);
#endif
	kfree(bat->temp_lookup.table);
err_volt_free:
	kfree(bat->volt_lookup.table);
err_percent_free:
	kfree(bat->percent_lookup.table);
err_gpio_en_free:
	gpio_free(pdata->gpio_en);
err_gpio_chg_free:
	gpio_free(pdata->gpio_chg);
err_gpio_pok_free:
	gpio_free(pdata->gpio_pok);
err_free:
	kfree(bat);
err_free_adc:
	s3c_adc_release(client);
	return ret;
}
Пример #11
0
/**
 * s3c_hwmon_probe - device probe entry.
 * @dev: The device being probed.
*/
static int __devinit s3c_hwmon_probe(struct platform_device *dev)
{
    struct s3c_hwmon_pdata *pdata = dev->dev.platform_data;
    struct s3c_hwmon *hwmon;
    int ret = 0;
    int i;

    if (!pdata) {
        dev_err(&dev->dev, "no platform data supplied\n");
        return -EINVAL;
    }

    shwmon = hwmon = kzalloc(sizeof(struct s3c_hwmon), GFP_KERNEL);
    if (hwmon == NULL) {
        dev_err(&dev->dev, "no memory\n");
        return -ENOMEM;
    }

    platform_set_drvdata(dev, hwmon);

    mutex_init(&hwmon->lock);

    /* Register with the core ADC driver. */

    hwmon->client = s3c_adc_register(dev, NULL, NULL, 0);
    if (IS_ERR(hwmon->client)) {
        dev_err(&dev->dev, "cannot register adc\n");
        ret = PTR_ERR(hwmon->client);
        goto err_mem;
    }

    /* add attributes for our adc devices. */

    ret = s3c_hwmon_add_raw(&dev->dev);
    if (ret)
        goto err_registered;

    /* register with the hwmon core */

    hwmon->hwmon_dev = hwmon_device_register(&dev->dev);
    if (IS_ERR(hwmon->hwmon_dev)) {
        dev_err(&dev->dev, "error registering with hwmon\n");
        ret = PTR_ERR(hwmon->hwmon_dev);
        goto err_raw_attribute;
    }

    for (i = 0; i < ARRAY_SIZE(pdata->in); i++) {
        struct s3c_hwmon_chcfg *cfg = pdata->in[i];

        if (!cfg)
            continue;

        if (cfg->mult >= 0x10000)
            dev_warn(&dev->dev,
                     "channel %d multiplier too large\n",
                     i);

        if (cfg->div == 0) {
            dev_err(&dev->dev, "channel %d divider zero\n", i);
            continue;
        }

        ret = s3c_hwmon_create_attr(&dev->dev, pdata->in[i],
                                    &hwmon->attrs[i], i);
        if (ret) {
            dev_err(&dev->dev,
                    "error creating channel %d\n", i);

            for (i--; i >= 0; i--)
                s3c_hwmon_remove_attr(&dev->dev,
                                      &hwmon->attrs[i]);

            goto err_hwmon_register;
        }
    }

    return 0;

err_hwmon_register:
    hwmon_device_unregister(hwmon->hwmon_dev);

err_raw_attribute:
    s3c_hwmon_remove_raw(&dev->dev);

err_registered:
    s3c_adc_release(hwmon->client);

err_mem:
    kfree(hwmon);
    return ret;
}
static bool sec_bat_adc_ap_exit(void)
{
	s3c_adc_release(adc_client);
	return true;
}
Пример #13
0
static int gp2a_i2c_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct input_dev *input_dev;
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *pdata = client->dev.platform_data;

	pr_info("==============================\n");
	pr_info("=========     GP2A     =======\n");
	pr_info("==============================\n");

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return ret;
	}
	/*
	if (!pdata->power || !pdata->light_adc_value) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return ret;
	}
	*/
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s: i2c functionality check failed!\n", __func__);
		return ret;
	}

	gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
	if (!gp2a) {
		pr_err("%s: failed to alloc memory for module data\n",
			__func__);
		return -ENOMEM;
	}

#if defined(CONFIG_OPTICAL_WAKE_ENABLE)
	if (system_rev >= 0x03) {
		pr_info("GP2A Reset GPIO = GPX0(1) (rev%02d)\n", system_rev);
		gp2a->enable_wakeup = true;
	} else {
		pr_info("GP2A Reset GPIO = GPL0(6) (rev%02d)\n", system_rev);
		gp2a->enable_wakeup = false;
	}
#else
	gp2a->enable_wakeup = false;
#endif

	gp2a->pdata = pdata;
	gp2a->i2c_client = client;
	i2c_set_clientdata(client, gp2a);

	/* wake lock init */
	wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
			"prx_wake_lock");
	mutex_init(&gp2a->power_mutex);
	mutex_init(&gp2a->adc_mutex);

	ret = gp2a_setup_irq(gp2a);
	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	/* allocate proximity input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		goto err_input_allocate_device_proximity;
	}

	gp2a->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, gp2a);
	input_dev->name = "proximity_sensor";
	input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
	input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);

	gp2a_dbgmsg("registering proximity input device\n");
	ret = input_register_device(input_dev);
	if (ret < 0) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(input_dev);
		goto err_input_register_device_proximity;
	}

	ret = sysfs_create_group(&input_dev->dev.kobj,
				 &proximity_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_proximity;
	}

	/* hrtimer settings.  we poll for light values using a timer. */
	hrtimer_init(&gp2a->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	gp2a->light_poll_delay =
			ns_to_ktime(LIGHT_TIMER_PERIOD_MS * NSEC_PER_MSEC);
	gp2a->timer.function = gp2a_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	gp2a->wq = create_singlethread_workqueue("gp2a_wq");
	if (!gp2a->wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}

	/* this is the thread function we run on the work queue */
	INIT_WORK(&gp2a->work_light, gp2a_work_func_light);

#ifdef GP2A_MODE_B
	/* this is the thread function we run on the work queue */
	INIT_WORK(&gp2a->work_proximity, gp2a_work_func_proximity);
#endif

	/* allocate lightsensor-level input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		ret = -ENOMEM;
		goto err_input_allocate_device_light;
	}

	input_set_drvdata(input_dev, gp2a);
	input_dev->name = "light_sensor";
	input_set_capability(input_dev, EV_ABS, ABS_MISC);
	input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);

	gp2a_dbgmsg("registering lightsensor-level input device\n");
	ret = input_register_device(input_dev);
	if (ret < 0) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(input_dev);
		goto err_input_register_device_light;
	}

	gp2a->light_input_dev = input_dev;
	ret = sysfs_create_group(&input_dev->dev.kobj,
				&light_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}

	/* alloc platform device for adc client */
	pdev_gp2a_adc = platform_device_alloc("gp2a-adc", -1);
	if (!pdev_gp2a_adc) {
		pr_err("%s: could not allocation pdev_gp2a_adc.\n", __func__);
		ret = -ENOMEM;
		goto err_platform_allocate_device_adc;
	}

	/* Register adc client */
	gp2a->padc = s3c_adc_register(pdev_gp2a_adc, NULL, NULL, 0);

	if (IS_ERR(gp2a->padc)) {
		dev_err(&pdev_gp2a_adc->dev, "cannot register adc\n");
		ret = PTR_ERR(gp2a->padc);
		goto err_platform_register_device_adc;
	}

	/* set sysfs for light sensor */

	ret = misc_register(&light_device);
	if (ret)
		pr_err(KERN_ERR "misc_register failed - light\n");

	gp2a->lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(gp2a->lightsensor_class))
		pr_err("Failed to create class(lightsensor)!\n");

	gp2a->switch_cmd_dev = device_create(gp2a->lightsensor_class,
		NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(gp2a->switch_cmd_dev))
		pr_err("Failed to create device(switch_cmd_dev)!\n");

	if (device_create_file(gp2a->switch_cmd_dev,
		&dev_attr_lightsensor_file_illuminance) < 0)
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_lightsensor_file_illuminance.attr.name);

	dev_set_drvdata(gp2a->switch_cmd_dev, gp2a);

	/* set initial proximity value as 1 */
	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
	input_sync(gp2a->proximity_input_dev);

	gp2a->adc_total = 0;

	goto done;

	/* error, unwind it all */
err_sysfs_create_group_light:
	input_unregister_device(gp2a->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(gp2a->wq);
err_platform_allocate_device_adc:
	platform_device_unregister(pdev_gp2a_adc);
err_platform_register_device_adc:
	s3c_adc_release(gp2a->padc);
err_create_workqueue:
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			&proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
	free_irq(gp2a->irq, 0);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
	mutex_destroy(&gp2a->adc_mutex);
	mutex_destroy(&gp2a->power_mutex);

	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	return ret;
}
Пример #14
0
static int __devinit gpio_switch_probe(struct platform_device *pdev)
{
	struct gpio_switch_platform_data *pdata = pdev->dev.platform_data;
	int ret = 0;

	if (!pdata)
		return -EBUSY;

	switch_data = kzalloc(sizeof(struct gpio_switch_data), GFP_KERNEL);
	if (!switch_data)
		return -ENOMEM;

	platform_set_drvdata(pdev, switch_data);
	switch_data->sdev.name = pdata->name;
	switch_data->gpio = pdata->gpio;
	switch_data->name_on = pdata->name_on;
	switch_data->name_off = pdata->name_off;
	switch_data->state_on = pdata->state_on;
	switch_data->state_off = pdata->state_off;
	switch_data->sdev.print_state = switch_gpio_print_state;
	
	switch_data->active_level = pdata->active_level;
	switch_data->adc_channel = pdata->adc_channel;
	
	ret = switch_dev_register(&switch_data->sdev);
	if (ret < 0)
		goto err_switch_dev_register;

	ret = gpio_request(switch_data->gpio, pdev->name);
	if (ret < 0)
		goto err_request_gpio;

	ret = gpio_direction_input(switch_data->gpio);
	if (ret < 0)
		goto err_set_gpio_input;

	INIT_DELAYED_WORK(&switch_data->del_work, gpio_switch_work);
	INIT_WORK(&mic_adc_work, mic_adc_work_func);

	mic_input_dev = input_allocate_device();
	mic_input_dev->name = "mx-mic-input";
	mic_input_dev->phys = "mx-mic-input/input0";
	if (input_register_device(mic_input_dev) != 0) {
		input_free_device(mic_input_dev);
		goto err_request_irq;
	}

	set_bit(EV_KEY, mic_input_dev->evbit);
	set_bit(KEY_FORWARDMAIL, mic_input_dev->keybit);

	switch_data->client = s3c_adc_register(pdev, NULL, NULL, 0);
	if (IS_ERR(switch_data->client)) {
		dev_err(&pdev->dev, "cannot register adc\n");
		ret = PTR_ERR(switch_data->client);
		goto err_request_adc;
	}

	setup_timer(&detect_mic_adc_timer, mic_adc_detect_timer_func, 0);
	
	s3c_gpio_setpull(switch_data->gpio, S3C_GPIO_PULL_UP);

	switch_data->irq = gpio_to_irq(switch_data->gpio);
	if (switch_data->irq < 0) {
		ret = switch_data->irq;
		goto err_detect_irq_num_failed;
	}

	ret = request_threaded_irq(switch_data->irq, NULL, gpio_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, pdev->name, switch_data);
	
	if (ret < 0)
		goto err_request_irq;

#ifdef CONFIG_EARLYSUSPEND
	switch_data->early_suspends.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
	switch_data->early_suspends.suspend = gpio_switch_early_suspend;
	switch_data->early_suspends.resume= gpio_switch_late_resume;
	register_early_suspend(&switch_data->early_suspends);
#endif
	schedule_delayed_work(&switch_data->del_work, msecs_to_jiffies(10));

	return 0;

err_request_irq:
	s3c_adc_release(switch_data->client);
err_request_adc:
err_detect_irq_num_failed:
err_set_gpio_input:
	gpio_free(switch_data->gpio);
err_request_gpio:
	switch_dev_unregister(&switch_data->sdev);
err_switch_dev_register:
	kfree(switch_data);

	return ret;
}