コード例 #1
0
static int __devinit apds9190_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
		struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
		struct apds9190_data *data;
		struct proximity_platform_data		*pdata;
		pm_message_t dummy_state;
		int err = 0;

		if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
				err = -EIO;
				goto exit;
		}

		data = kzalloc(sizeof(struct apds9190_data), GFP_KERNEL);
		apds_9190_i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
		if (!data) {
				err = -ENOMEM;
				goto exit;
		}

		memset(data, 0x00, sizeof(struct apds9190_data));

		INIT_WORK(&data->dwork, apds_9190_irq_work_func);		

		data->client = client;
		apds_9190_i2c_client = client;
		i2c_set_clientdata(data->client, data);

		data->input_dev = input_allocate_device();		

		data->input_dev->name = "proximity";
		data->input_dev->phys = "proximity/input2";	
		set_bit(EV_SYN, data->input_dev->evbit);
		set_bit(EV_ABS, data->input_dev->evbit);
		input_set_abs_params(data->input_dev, ABS_DISTANCE, 0, 1, 0, 0);

		err = input_register_device(data->input_dev);

		if (err) {
				DEBUG_MSG("Unable to register input device: %s\n",
								data->input_dev->name);
				goto exit_input_register_device_failed;
		}

		pdata = data->client->dev.platform_data;
		if(NULL == pdata){
				printk(KERN_INFO "platform data is NULL");
				return -1;
		}

		methods = pdata->methods;

		data->irq = gpio_to_irq(pdata->irq_num);

		spin_lock_init(&data->lock);
		mutex_init(&data->update_lock);

		data->enable = 0;	/* default mode is standard */
		dev_info(&client->dev, "enable = %s\n", data->enable ? "1" : "0");

		err = pdata->power(1);
		if(err < 0) {
			printk(KERN_INFO "%s,Proximity Power On Fail in Probe\n",__func__);
			goto exit_kfree;
		}
		
		mdelay(50);

		/* Initialize the APDS9190 chip */
		err = apds9190_init_client(apds_9190_i2c_client);
		if(err < 0) {
			printk(KERN_INFO "%s,Proximity apds9190_init_client Fail in Probe\n",__func__);
			goto exit_kfree;
		}
		
		err = apds_9190_initialize();	
		if(err < 0) {
			printk(KERN_INFO "%s,Proximity apds_9190_initialize Fail in Probe\n",__func__);
			goto exit_kfree;
		}
		
		if(request_irq(data->irq,apds_9190_irq_handler,IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,"proximity_irq", data) < 0){
				err = -EIO;
				goto exit_request_irq_failed;
		}
		err = set_irq_wake(data->irq, 1);
		if (err)
			set_irq_wake(data->irq, 0);

			
		data->sw_mode = PROX_STAT_OPERATING;

		/* Register sysfs hooks */
		err = sysfs_create_group(&client->dev.kobj, &apds9190_attr_group);
		if (err)
				goto exit_kfree;

		dummy_state.event = 0;
		apds9190_suspend(data->client, dummy_state);


		return 0;
exit_input_register_device_failed:	
exit_request_irq_failed:
exit_kfree:
		dev_info(&client->dev, "probe error\n");
		kfree(data);
exit:
		return err;
}
int ssp_sensorhub_initialize(struct ssp_data *ssp_data)
{
	struct ssp_sensorhub_data *hub_data;
	int ret;

	/* allocate memory for sensorhub data */
	hub_data = kzalloc(sizeof(*hub_data), GFP_KERNEL);
	if (!hub_data) {
		sensorhub_err("allocate memory for sensorhub data err");
		ret = -ENOMEM;
		goto exit;
	}
	hub_data->ssp_data = ssp_data;
	ssp_data->hub_data = hub_data;

	/* init wakelock, list, waitqueue, completion and spinlock */
	wake_lock_init(&hub_data->sensorhub_wake_lock, WAKE_LOCK_SUSPEND,
			"ssp_sensorhub_wake_lock");
	init_waitqueue_head(&hub_data->sensorhub_wq);
	init_completion(&hub_data->read_done);
	init_completion(&hub_data->big_read_done);
	init_completion(&hub_data->big_write_done);
	spin_lock_init(&hub_data->sensorhub_lock);

	/* allocate sensorhub input device */
	hub_data->sensorhub_input_dev = input_allocate_device();
	if (!hub_data->sensorhub_input_dev) {
		sensorhub_err("allocate sensorhub input device err");
		ret = -ENOMEM;
		goto err_input_allocate_device_sensorhub;
	}

	/* set sensorhub input device */
	input_set_drvdata(hub_data->sensorhub_input_dev, hub_data);
	hub_data->sensorhub_input_dev->name = "ssp_context";
	input_set_capability(hub_data->sensorhub_input_dev, EV_REL, DATA);
	input_set_capability(hub_data->sensorhub_input_dev, EV_REL, BIG_DATA);
	input_set_capability(hub_data->sensorhub_input_dev, EV_REL, NOTICE);

	/* register sensorhub input device */
	ret = input_register_device(hub_data->sensorhub_input_dev);
	if (ret < 0) {
		sensorhub_err("register sensorhub input device err(%d)", ret);
		input_free_device(hub_data->sensorhub_input_dev);
		goto err_input_register_device_sensorhub;
	}

	/* register sensorhub misc device */
	hub_data->sensorhub_device.minor = MISC_DYNAMIC_MINOR;
	hub_data->sensorhub_device.name = "ssp_sensorhub";
	hub_data->sensorhub_device.fops = &ssp_sensorhub_fops;

	ret = misc_register(&hub_data->sensorhub_device);
	if (ret < 0) {
		sensorhub_err("register sensorhub misc device err(%d)", ret);
		goto err_misc_register;
	}

	/* allocate fifo */
	ret = kfifo_alloc(&hub_data->fifo,
		sizeof(void *) * LIST_SIZE, GFP_KERNEL);
	if (ret) {
		sensorhub_err("kfifo allocate err(%d)", ret);
		goto err_kfifo_alloc;
	}

	/* create and run sensorhub thread */
	hub_data->sensorhub_task = kthread_run(ssp_sensorhub_thread,
				(void *)hub_data, "ssp_sensorhub_thread");
	if (IS_ERR(hub_data->sensorhub_task)) {
		ret = PTR_ERR(hub_data->sensorhub_task);
		goto err_kthread_run;
	}

	return 0;

err_kthread_run:
	kfifo_free(&hub_data->fifo);
err_kfifo_alloc:
	misc_deregister(&hub_data->sensorhub_device);
err_misc_register:
	input_unregister_device(hub_data->sensorhub_input_dev);
err_input_register_device_sensorhub:
err_input_allocate_device_sensorhub:
	complete_all(&hub_data->big_write_done);
	complete_all(&hub_data->big_read_done);
	complete_all(&hub_data->read_done);
	wake_lock_destroy(&hub_data->sensorhub_wake_lock);
	kfree(hub_data);
exit:
	return ret;
}
コード例 #3
0
static int __devinit gpio_keys_probe(struct platform_device *pdev)
{
    const struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
    struct gpio_keys_drvdata *ddata;
    struct device *dev = &pdev->dev;
    struct gpio_keys_platform_data alt_pdata;
    struct input_dev *input;
    int i, error;
    int wakeup = 0;

    if (!pdata) {
        error = gpio_keys_get_devtree_pdata(dev, &alt_pdata);
        if (error)
            return error;
        pdata = &alt_pdata;
    }

    ddata = kzalloc(sizeof(struct gpio_keys_drvdata) +
                    pdata->nbuttons * sizeof(struct gpio_button_data),
                    GFP_KERNEL);
    input = input_allocate_device();
    if (!ddata || !input) {
        dev_err(dev, "failed to allocate state\n");
        error = -ENOMEM;
        goto fail1;
    }

    ddata->input = input;
    ddata->n_buttons = pdata->nbuttons;
    ddata->enable = pdata->enable;
    ddata->disable = pdata->disable;
    mutex_init(&ddata->disable_lock);

    platform_set_drvdata(pdev, ddata);
    input_set_drvdata(input, ddata);

    input->name = pdata->name ? : pdev->name;
    input->phys = "gpio-keys/input0";
    input->dev.parent = &pdev->dev;
    input->open = gpio_keys_open;
    input->close = gpio_keys_close;

    input->id.bustype = BUS_HOST;
    input->id.vendor = 0x0001;
    input->id.product = 0x0001;
    input->id.version = 0x0100;

    /* Enable auto repeat feature of Linux input subsystem */
    if (pdata->rep)
        __set_bit(EV_REP, input->evbit);

    for (i = 0; i < pdata->nbuttons; i++) {
        const struct gpio_keys_button *button = &pdata->buttons[i];
        struct gpio_button_data *bdata = &ddata->data[i];

        error = gpio_keys_setup_key(pdev, input, bdata, button);
        if (error)
            goto fail2;

        if (button->wakeup)
            wakeup = 1;
    }

    error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group);
    if (error) {
        dev_err(dev, "Unable to export keys/switches, error: %d\n",
                error);
        goto fail2;
    }

    error = input_register_device(input);
    if (error) {
        dev_err(dev, "Unable to register input device, error: %d\n",
                error);
        goto fail3;
    }

    /* get current state of buttons that are connected to GPIOs */
    for (i = 0; i < pdata->nbuttons; i++) {
        struct gpio_button_data *bdata = &ddata->data[i];
        if (gpio_is_valid(bdata->button->gpio))
            gpio_keys_gpio_report_event(bdata);
    }
    input_sync(input);

    device_init_wakeup(&pdev->dev, wakeup);

    return 0;

fail3:
    sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
fail2:
    while (--i >= 0)
        gpio_remove_key(&ddata->data[i]);

    platform_set_drvdata(pdev, NULL);
fail1:
    input_free_device(input);
    kfree(ddata);
    /* If we have no platform_data, we allocated buttons dynamically. */
    if (!pdev->dev.platform_data)
        kfree(pdata->buttons);

    return error;
}
コード例 #4
0
// Pantech Earjack Probe Function
static int __devinit pantech_earjack_probe(struct platform_device *pdev)
{
	int rc = 0;
	int err = 0;
	struct input_dev *ipdev;

	dbg_func_in();

	irq_state = 0;

	// Alloc Devices
	earjack = kzalloc(sizeof(struct pantech_earjack), GFP_KERNEL);
	if (!earjack)
		return -ENOMEM;

	earjack->sdev.name	= "h2w";   
  
	earjack->sdev.print_name = msm_headset_print_name;
	rc = switch_dev_register(&earjack->sdev);
	if (rc)
		goto err_switch_dev_register;

	ipdev = input_allocate_device();
	if (!ipdev) {
		rc = -ENOMEM;
		goto err_alloc_input_dev;
	}
	input_set_drvdata(ipdev, earjack);


	// Init Status Flags
	earjack->ipdev = ipdev;
	earjack->car_kit = 0;
	earjack->type=EARJACK_STATE_OFF;
	earjack->remotekey_pressed = 0;
	earjack->remotekey_index = 0;

	// Initialize Work Queue
	INIT_DELAYED_WORK(&earjack_work,earjack_detect_func);          // INIT WORK
	INIT_DELAYED_WORK(&remotekey_work,remotekey_detect_func);

	// Get Power Source
#if defined(CONFIG_MIC_BIAS_1_8V)
	err = 0;
#else
	hs_jack_l8 = regulator_get(NULL, "8058_l8");
	regulator_set_voltage(hs_jack_l8,2700000,2700000);

	dbg("regulator_enable hs_jack_l8 value => %d\n",err);
#endif

	// Initialize Wakelocks
	wake_lock_init(&earjack_wake_lock, WAKE_LOCK_SUSPEND, "earjack_wake_lock_init");
	wake_lock_init(&remotekey_wake_lock, WAKE_LOCK_SUSPEND, "remotekey_wake_lock_init");

	// Setup GPIO's
	gpio_request(EARJACK_DET, "earjack_det");
	gpio_request(REMOTEKEY_DET, "remotekey_det");
	gpio_tlmm_config(GPIO_CFG(EARJACK_DET, 0, GPIO_CFG_INPUT,GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
	rc = request_irq(gpio_to_irq(EARJACK_DET), Earjack_Det_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "earjack_det-irq", earjack);

	// Warning: REMOTEKEY_DET using default gpio config.
	//gpio_tlmm_config(GPIO_CFG(REMOTEKEY_DET, 0, GPIO_CFG_INPUT,GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
	
	irq_set_irq_wake(gpio_to_irq(EARJACK_DET), 1);
	irq_set_irq_wake(gpio_to_irq(REMOTEKEY_DET), 1);

	// Init Input Device
//pz1946 merge for wired long key
#ifdef CONFIG_MACH_MSM8X60_PRESTO
	ipdev->name	= DRIVER_NAME;
	ipdev->id.vendor    = 0;
	ipdev->id.product   = 0;
	ipdev->id.version   = 0;
#else	
	ipdev->id.vendor    = 0x0001;
	ipdev->id.product   = 1;
	ipdev->id.version   = 1;
#endif

	input_set_capability(ipdev, EV_KEY, KEY_MEDIA);
	input_set_capability(ipdev, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(ipdev, EV_KEY, KEY_VOLUMEDOWN);
	input_set_capability(ipdev, EV_KEY, KEY_POWER);    
	input_set_capability(ipdev, EV_KEY, KEY_END);
	input_set_capability(ipdev, EV_SW,  SW_HEADPHONE_INSERT);
	input_set_capability(ipdev, EV_SW,  SW_MICROPHONE_INSERT);

	rc = input_register_device(ipdev);
	if (rc) {
		dev_err(&ipdev->dev,
				"hs_probe: input_register_device rc=%d\n", rc);
		goto err_reg_input_dev;
	}
	platform_set_drvdata(pdev, earjack);

	rc = sysfs_create_group(&pdev->dev.kobj, &dev_attr_grp);
	if (rc) {
		dev_err(&ipdev->dev,
				"hs_probe: sysfs_create_group rc=%d\n", rc);
		goto err_earjack_init;
	}

	// Scehdule earjack_detect_func for initial detect
	disable_irq_detect(); //disable_irq_nosync(gpio_to_irq(EARJACK_DET));
	
	wake_lock(&earjack_wake_lock);
	disable_irq_nosync(gpio_to_irq(REMOTEKEY_DET));

	schedule_delayed_work(&earjack_work,10);    // after 100ms
	
	dbg_func_out();
	return 0;

err_earjack_init:

err_reg_input_dev:
	input_unregister_device(ipdev);
	ipdev = NULL;
err_alloc_input_dev:
	input_free_device(ipdev);
err_switch_dev_register:
	kfree(earjack);
	return 0;
}
コード例 #5
0
ファイル: imx_keypad.c プロジェクト: AmesianX/netlink-mmap
static int __devinit imx_keypad_probe(struct platform_device *pdev)
{
	const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data;
	struct imx_keypad *keypad;
	struct input_dev *input_dev;
	struct resource *res;
	int irq, error, i;

	if (keymap_data == NULL) {
		dev_err(&pdev->dev, "no keymap defined\n");
		return -EINVAL;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "no irq defined in platform data\n");
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "no I/O memory defined in platform data\n");
		return -EINVAL;
	}

	res = request_mem_region(res->start, resource_size(res), pdev->name);
	if (res == NULL) {
		dev_err(&pdev->dev, "failed to request I/O memory\n");
		return -EBUSY;
	}

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&pdev->dev, "failed to allocate the input device\n");
		error = -ENOMEM;
		goto failed_rel_mem;
	}

	keypad = kzalloc(sizeof(struct imx_keypad), GFP_KERNEL);
	if (!keypad) {
		dev_err(&pdev->dev, "not enough memory for driver data\n");
		error = -ENOMEM;
		goto failed_free_input;
	}

	keypad->input_dev = input_dev;
	keypad->irq = irq;
	keypad->stable_count = 0;

	setup_timer(&keypad->check_matrix_timer,
		    imx_keypad_check_for_events, (unsigned long) keypad);

	keypad->mmio_base = ioremap(res->start, resource_size(res));
	if (keypad->mmio_base == NULL) {
		dev_err(&pdev->dev, "failed to remap I/O memory\n");
		error = -ENOMEM;
		goto failed_free_priv;
	}

	keypad->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(keypad->clk)) {
		dev_err(&pdev->dev, "failed to get keypad clock\n");
		error = PTR_ERR(keypad->clk);
		goto failed_unmap;
	}

	/* Search for rows and cols enabled */
	for (i = 0; i < keymap_data->keymap_size; i++) {
		keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]);
		keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]);
	}

	if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) ||
	    keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) {
		dev_err(&pdev->dev,
			"invalid key data (too many rows or colums)\n");
		error = -EINVAL;
		goto failed_clock_put;
	}
	dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask);
	dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask);

	/* Init the Input device */
	input_dev->name = pdev->name;
	input_dev->id.bustype = BUS_HOST;
	input_dev->dev.parent = &pdev->dev;
	input_dev->open = imx_keypad_open;
	input_dev->close = imx_keypad_close;

	error = matrix_keypad_build_keymap(keymap_data, NULL,
					   MAX_MATRIX_KEY_ROWS,
					   MAX_MATRIX_KEY_COLS,
					   keypad->keycodes, input_dev);
	if (error) {
		dev_err(&pdev->dev, "failed to build keymap\n");
		goto failed_clock_put;
	}

	__set_bit(EV_REP, input_dev->evbit);
	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
	input_set_drvdata(input_dev, keypad);

	/* Ensure that the keypad will stay dormant until opened */
	imx_keypad_inhibit(keypad);

	error = request_irq(irq, imx_keypad_irq_handler, 0,
			    pdev->name, keypad);
	if (error) {
		dev_err(&pdev->dev, "failed to request IRQ\n");
		goto failed_clock_put;
	}

	/* Register the input device */
	error = input_register_device(input_dev);
	if (error) {
		dev_err(&pdev->dev, "failed to register input device\n");
		goto failed_free_irq;
	}

	platform_set_drvdata(pdev, keypad);
	device_init_wakeup(&pdev->dev, 1);

	return 0;

failed_free_irq:
	free_irq(irq, pdev);
failed_clock_put:
	clk_put(keypad->clk);
failed_unmap:
	iounmap(keypad->mmio_base);
failed_free_priv:
	kfree(keypad);
failed_free_input:
	input_free_device(input_dev);
failed_rel_mem:
	release_mem_region(res->start, resource_size(res));
	return error;
}
コード例 #6
0
static int ab8500_ponkey_probe(struct platform_device *pdev)
{
	struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
	struct ab8500_ponkey *ponkey;
	struct input_dev *input;
	int irq_dbf, irq_dbr;
	int error;

	irq_dbf = platform_get_irq_byname(pdev, "ONKEY_DBF");
	if (irq_dbf < 0) {
		dev_err(&pdev->dev, "No IRQ for ONKEY_DBF, error=%d\n", irq_dbf);
		return irq_dbf;
	}

	irq_dbr = platform_get_irq_byname(pdev, "ONKEY_DBR");
	if (irq_dbr < 0) {
		dev_err(&pdev->dev, "No IRQ for ONKEY_DBR, error=%d\n", irq_dbr);
		return irq_dbr;
	}

	ponkey = kzalloc(sizeof(struct ab8500_ponkey), GFP_KERNEL);
	input = input_allocate_device();
	if (!ponkey || !input) {
		error = -ENOMEM;
		goto err_free_mem;
	}

	ponkey->idev = input;
	ponkey->ab8500 = ab8500;
	ponkey->irq_dbf = irq_dbf;
	ponkey->irq_dbr = irq_dbr;

	input->name = "AB8500 POn(PowerOn) Key";
	input->dev.parent = &pdev->dev;

	input_set_capability(input, EV_KEY, KEY_POWER);

	error = request_any_context_irq(ponkey->irq_dbf, ab8500_ponkey_handler,
					0, "ab8500-ponkey-dbf", ponkey);
	if (error < 0) {
		dev_err(ab8500->dev, "Failed to request dbf IRQ#%d: %d\n",
			ponkey->irq_dbf, error);
		goto err_free_mem;
	}

	error = request_any_context_irq(ponkey->irq_dbr, ab8500_ponkey_handler,
					0, "ab8500-ponkey-dbr", ponkey);
	if (error < 0) {
		dev_err(ab8500->dev, "Failed to request dbr IRQ#%d: %d\n",
			ponkey->irq_dbr, error);
		goto err_free_dbf_irq;
	}

	error = input_register_device(ponkey->idev);
	if (error) {
		dev_err(ab8500->dev, "Can't register input device: %d\n", error);
		goto err_free_dbr_irq;
	}

	platform_set_drvdata(pdev, ponkey);
	return 0;

err_free_dbr_irq:
	free_irq(ponkey->irq_dbr, ponkey);
err_free_dbf_irq:
	free_irq(ponkey->irq_dbf, ponkey);
err_free_mem:
	input_free_device(input);
	kfree(ponkey);

	return error;
}
コード例 #7
0
static int tc300k_fw_check(struct tc300k_data *data)
{
	struct i2c_client *client = data->client;
	int ret;
	bool update = false;

	ret = get_fw_version(data, true);
	if (ret < 0) {
#if 0
		if (info->pdata->lcd_connect) {
			/* tsp connect check */
			dev_err(&client->dev,
				"%s: i2c fail. but lcd connected\n",
				__func__);
			dev_err(&client->dev,
				"excute firm update\n");
			update = true;
		} else {
#endif
		dev_err(&client->dev,
			"%s: i2c fail...[%d], addr[%d]\n",
			__func__, ret, data->client->addr);
		dev_err(&client->dev,
			"%s: touchkey driver unload\n", __func__);
		return ret;
	}

	if (data->fw_ver < TC300K_FIRMWARE_VER) {
		dev_notice(&client->dev,
			"fw_version check excute firmware update(0x%x, 0x%x)\n",
			data->fw_ver, TC300K_FIRMWARE_VER);
		update = true;
	}

	if (update) {
		ret = tc300k_fw_update(data, FW_INKERNEL, true);
		if (ret)
			return -1;
	}

	return 0;
}

static int __devinit tc300k_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct input_dev *input_dev;
	struct tc300k_data *data;
	int ret;
	int i;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev,
			"i2c_check_functionality fail\n");
		return -EIO;
	}

	data = kzalloc(sizeof(struct tc300k_data), GFP_KERNEL);
	if (!data) {
		dev_err(&client->dev, "Failed to allocate memory\n");
		ret = -ENOMEM;
		goto err_alloc_data;
	}

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&client->dev,
			"Failed to allocate memory for input device\n");
		ret = -ENOMEM;
		goto err_alloc_input;
	}

	data->client = client;
	data->input_dev = input_dev;
	data->pdata = client->dev.platform_data;
	if (data->pdata == NULL) {
		pr_err("failed to get platform data\n");
		ret = -EINVAL;
		goto err_platform_data;
	}
	data->irq = -1;
	mutex_init(&data->lock);

	data->key_num = data->pdata->key_num;
	dev_info(&client->dev, "number of keys = %d\n", data->key_num);
	data->keycode = data->pdata->keycode;
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
	for (i = 1; i < data->key_num; i++)
		dev_info(&client->dev, "keycode[%d]= %3d\n", i, data->keycode[i]);
#endif
	i2c_set_clientdata(client, data);

	data->pdata->keyled(true);
	data->pdata->power(true);
	data->enabled = true;

	msleep(TC300K_POWERON_DELAY);

	ret = tc300k_fw_check(data);
	if (ret) {
		dev_err(&client->dev,
			"failed to firmware check(%d)\n", ret);
		goto err_fw_check;
	}

	snprintf(data->phys, sizeof(data->phys),
		"%s/input0", dev_name(&client->dev));
	input_dev->name = "sec_touchkey";
	input_dev->phys = data->phys;
	input_dev->id.bustype = BUS_I2C;
	input_dev->dev.parent = &client->dev;
	input_dev->open = tc300k_input_open;
	input_dev->close = tc300k_input_close;

	set_bit(EV_KEY, input_dev->evbit);
	set_bit(EV_LED, input_dev->evbit);
	set_bit(LED_MISC, input_dev->ledbit);
	for (i = 1; i < data->key_num; i++)
		set_bit(data->keycode[i], input_dev->keybit);
	input_set_drvdata(input_dev, data);

	ret = input_register_device(input_dev);
	if (ret) {
		dev_err(&client->dev, "fail to register input_dev (%d)\n",
			ret);
		goto err_register_input_dev;
	}

	ret = request_threaded_irq(client->irq, NULL, tc300k_interrupt,
				IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				TC300K_NAME, data);
	if (ret < 0) {
		dev_err(&client->dev, "fail to request irq (%d).\n",
			client->irq);
		goto err_request_irq;
	}
	data->irq = client->irq;

#ifdef CONFIG_HAS_EARLYSUSPEND
	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	data->early_suspend.suspend = tc300k_early_suspend;
	data->early_suspend.resume = tc300k_late_resume;
	register_early_suspend(&data->early_suspend);
#endif

	data->sec_touchkey = device_create(sec_class,
		NULL, 0, data, "sec_touchkey");
	if (IS_ERR(data->sec_touchkey))
		dev_err(&client->dev,
			"Failed to create device for the touchkey sysfs\n");

	ret = sysfs_create_group(&data->sec_touchkey->kobj,
		&sec_touchkey_attr_group);
	if (ret)
		dev_err(&client->dev, "Failed to create sysfs group\n");

	dev_info(&client->dev, "%s done\n", __func__);
	return 0;

err_request_irq:
	input_unregister_device(input_dev);
err_register_input_dev:
err_fw_check:
	mutex_destroy(&data->lock);
	data->pdata->keyled(false);
	data->pdata->power(false);
err_platform_data:
	input_free_device(input_dev);
err_alloc_input:
	kfree(data);
err_alloc_data:
	return ret;
}

static int __devexit tc300k_remove(struct i2c_client *client)
{
	struct tc300k_data *data = i2c_get_clientdata(client);

#ifdef CONFIG_HAS_EARLYSUSPEND
	unregister_early_suspend(&data->early_suspend);
#endif
	free_irq(data->irq, data);
	input_unregister_device(data->input_dev);
	input_free_device(data->input_dev);
	mutex_destroy(&data->lock);
	data->pdata->keyled(false);
	data->pdata->power(false);
	gpio_free(data->pdata->gpio_int);
	gpio_free(data->pdata->gpio_sda);
	gpio_free(data->pdata->gpio_scl);
	kfree(data);

	return 0;
}

static void tc300k_shutdown(struct i2c_client *client)
{
	struct tc300k_data *data = i2c_get_clientdata(client);

	data->pdata->keyled(false);
	data->pdata->power(false);
}

#if defined(CONFIG_PM)
static int tc300k_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct tc300k_data *data = i2c_get_clientdata(client);
	int i;
	int ret;

	mutex_lock(&data->lock);

	if (!data->enabled)
		return 0;

	dev_notice(&data->client->dev, "%s: users=%d\n",
		__func__, data->input_dev->users);

	disable_irq(data->irq);
	data->enabled = false;
	release_all_fingers(data);
	data->pdata->power(false);
	data->pdata->keyled(false);

	mutex_unlock(&data->lock);

	return 0;
}

static int tc300k_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct tc300k_data *data = i2c_get_clientdata(client);

	mutex_lock(&data->lock);

	if (data->enabled)
		return 0;

	dev_notice(&data->client->dev, "%s: users=%d\n",
		__func__, data->input_dev->users);

	data->enabled = true;
	data->pdata->keyled(true);
	data->pdata->power(true);
	msleep(50);
	enable_irq(data->irq);

	msleep(50);

	mutex_unlock(&data->lock);

	return 0;
}

#ifdef CONFIG_HAS_EARLYSUSPEND
static void tc300k_early_suspend(struct early_suspend *h)
{
	struct tc300k_data *data;
	data = container_of(h, struct tc300k_data, early_suspend);
	tc300k_suspend(&data->client->dev);
}

static void tc300k_late_resume(struct early_suspend *h)
{
	struct tc300k_data *data;
	data = container_of(h, struct tc300k_data, early_suspend);
	tc300k_resume(&data->client->dev);
}
#endif

static void tc300k_input_close(struct input_dev *dev)
{
	struct tc300k_data *data = input_get_drvdata(dev);
	dev_info(&data->client->dev, "%s: users=%d\n", __func__,
		   data->input_dev->users);

	tc300k_suspend(&data->client->dev);
}

static int tc300k_input_open(struct input_dev *dev)
{
	struct tc300k_data *data = input_get_drvdata(dev);

	dev_info(&data->client->dev, "%s: users=%d\n", __func__,
		   data->input_dev->users);

	tc300k_resume(&data->client->dev);

	return 0;
}
#endif /* CONFIG_PM */

#if 0
#if defined(CONFIG_PM) || defined(CONFIG_HAS_EARLYSUSPEND)
static const struct dev_pm_ops tc300k_pm_ops = {
	.suspend = tc300k_suspend,
	.resume = tc300k_resume,
};
#endif
#endif

static const struct i2c_device_id tc300k_id[] = {
	{TC300K_NAME, 0},
	{ }
};
MODULE_DEVICE_TABLE(i2c, tc300k_id);

static struct i2c_driver tc300k_driver = {
	.probe = tc300k_probe,
	.remove = __devexit_p(tc300k_remove),
	.shutdown = tc300k_shutdown,
	.driver = {
		.name = TC300K_NAME,
		.owner = THIS_MODULE,
#if 0
#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND)
		.pm	= &tc370_pm_ops,
#endif
#endif
	},
	.id_table = tc300k_id,
};
コード例 #8
0
static int i2c_touchkey_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	struct touchkey_platform_data *pdata = client->dev.platform_data;
	struct touchkey_i2c *tkey_i2c;

	struct input_dev *input_dev;
	int err = 0;
	unsigned char data;
	int i;
	int ret;

	printk(KERN_DEBUG "[TouchKey] i2c_touchkey_probe\n");

	if (pdata == NULL) {
		printk(KERN_ERR "%s: no pdata\n", __func__);
		return -ENODEV;
	}

	/*Check I2C functionality */
	ret = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
	if (ret == 0) {
		printk(KERN_ERR "[Touchkey] No I2C functionality found\n");
		ret = -ENODEV;
		return ret;
	}

	/*Obtain kernel memory space for touchkey i2c */
	tkey_i2c = kzalloc(sizeof(struct touchkey_i2c), GFP_KERNEL);
	if (NULL == tkey_i2c) {
		printk(KERN_ERR "[Touchkey] failed to allocate tkey_i2c.\n");
		return -ENOMEM;
	}

	input_dev = input_allocate_device();

	if (!input_dev) {
		printk(KERN_ERR"[Touchkey] failed to allocate input device\n");
		kfree(tkey_i2c);
		return -ENOMEM;
	}

	input_dev->name = "sec_touchkey";
	input_dev->phys = "sec_touchkey/input0";
	input_dev->id.bustype = BUS_HOST;
	input_dev->dev.parent = &client->dev;

	/*tkey_i2c*/
	tkey_i2c->pdata = pdata;
	tkey_i2c->input_dev = input_dev;
	tkey_i2c->client = client;
	tkey_i2c->irq = client->irq;
	tkey_i2c->name = "sec_touchkey";

	set_bit(EV_SYN, input_dev->evbit);
	set_bit(EV_LED, input_dev->evbit);
	set_bit(LED_MISC, input_dev->ledbit);
	set_bit(EV_KEY, input_dev->evbit);

	for (i = 1; i < touchkey_count; i++)
		set_bit(touchkey_keycode[i], input_dev->keybit);

	input_set_drvdata(input_dev, tkey_i2c);

	ret = input_register_device(input_dev);
	if (ret) {
		printk(KERN_ERR"[Touchkey] failed to register input device\n");
		input_free_device(input_dev);
		kfree(tkey_i2c);
		return err;
	}

	INIT_WORK(&tkey_i2c->update_work, touchkey_update_func);

	tkey_i2c->pdata->power_on(1);
	msleep(50);

	touchkey_enable = 1;
	data = 1;

	/*sysfs*/
	tkey_i2c->dev = device_create(sec_class, NULL, 0, NULL, "sec_touchkey");

	if (IS_ERR(tkey_i2c->dev)) {
		printk(KERN_ERR "Failed to create device(tkey_i2c->dev)!\n");
		input_unregister_device(input_dev);
	} else {
		dev_set_drvdata(tkey_i2c->dev, tkey_i2c);
		ret = sysfs_create_group(&tkey_i2c->dev->kobj,
					&touchkey_attr_group);
		if (ret) {
			printk(KERN_ERR
				"[TouchKey]: failed to create sysfs group\n");
		}
	}

	gpio_request(GPIO_OLED_DET, "OLED_DET");
	ret = gpio_get_value(GPIO_OLED_DET);
	printk(KERN_DEBUG
	"[TouchKey] OLED_DET = %d\n", ret);

	if (ret == 0) {
		printk(KERN_DEBUG
		"[TouchKey] device wasn't connected to board\n");

		input_unregister_device(input_dev);
		touchkey_probe = false;
		return -EBUSY;
	}

	ret =
		request_threaded_irq(tkey_i2c->irq, NULL, touchkey_interrupt,
				IRQF_DISABLED | IRQF_TRIGGER_FALLING |
				IRQF_ONESHOT, tkey_i2c->name, tkey_i2c);
	if (ret < 0) {
		printk(KERN_ERR
			"[Touchkey]: failed to request irq(%d) - %d\n",
			tkey_i2c->irq, ret);
		input_unregister_device(input_dev);
		touchkey_probe = false;
		return -EBUSY;
	}

	tkey_i2c->pdata->led_power_on(1);

#if defined(TK_HAS_FIRMWARE_UPDATE)
	ret = touchkey_firmware_update(tkey_i2c);
	if (ret < 0) {
		printk(KERN_ERR
			"[Touchkey]: failed firmware updating process (%d)\n",
			ret);
		input_unregister_device(input_dev);
		touchkey_probe = false;
		return -EBUSY;
	}
#endif

#ifdef CONFIG_HAS_EARLYSUSPEND
	tkey_i2c->early_suspend.suspend =
		(void *)sec_touchkey_early_suspend;
	tkey_i2c->early_suspend.resume =
		(void *)sec_touchkey_late_resume;
	register_early_suspend(&tkey_i2c->early_suspend);
#endif

#if defined(TK_HAS_AUTOCAL)
	touchkey_autocalibration(tkey_i2c);
#endif
	set_touchkey_debug('K');
	return 0;
}
コード例 #9
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 (!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);

/* new sysfs */
	ret = sensors_register(gp2a->light_dev, gp2a, light_sensor_attrs,
						"light_sensor");
	if (ret) {
		pr_err("%s: cound not register light sensor device(%d).\n",
		__func__, ret);
		goto out_light_sensor_register_failed;
	}

	ret = sensors_register(gp2a->proximity_dev,
			gp2a, proximity_sensor_attrs, "proximity_sensor");
	if (ret) {
		pr_err("%s: cound not register proximity sensor device(%d).\n",
		__func__, ret);
		goto out_proximity_sensor_register_failed;
	}

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

	goto done;

	/* error, unwind it all */
out_light_sensor_register_failed:
	sensors_unregister(gp2a->light_dev);
out_proximity_sensor_register_failed:
	sensors_unregister(gp2a->proximity_dev);

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;
}
コード例 #10
0
ファイル: rk28_mid_nx7005.c プロジェクト: Tigrouzen/k1099
static int __devinit rk28_AD_button_probe(struct platform_device *pdev)
{
	struct rk28_AD_button *AD_button;
	struct input_dev *input_dev;
	int  error,i;
	AD_button = kzalloc(sizeof(struct rk28_AD_button), GFP_KERNEL);
	/* Create and register the input driver. */
	input_dev = input_allocate_device();
	if (!input_dev || !AD_button) {
		dev_err(&pdev->dev, "failed to allocate input device\n");
		error = -ENOMEM;
		goto failed1;
	}

    //[email protected]
	int ret = request_irq(IRQ_NR_ADC, rk28_AD_irq_handler, 0, "ADC", NULL);
	if (ret < 0) {
		printk(KERN_CRIT "Can't register IRQ for ADC\n");
		return ret;
	}
	
	memcpy(AD_button->keycodes, initkey_code, sizeof(AD_button->keycodes));
	input_dev->name = pdev->name;
	input_dev->open = rk28_AD_button_open;
	input_dev->close = rk28_AD_button_close;
	input_dev->dev.parent = &pdev->dev;
	input_dev->phys = KEY_PHYS_NAME;
	input_dev->id.vendor = 0x0001;
	input_dev->id.product = 0x0001;
	input_dev->id.version = 0x0100;
	input_dev->keycode = AD_button->keycodes;
	input_dev->keycodesize = sizeof(unsigned char);
	input_dev->keycodemax = ARRAY_SIZE(initkey_code);
	for (i = 0; i < ARRAY_SIZE(initkey_code); i++)
		set_bit(initkey_code[i], input_dev->keybit);
	clear_bit(0, input_dev->keybit);

	AD_button->input_dev = input_dev;
	input_set_drvdata(input_dev, AD_button);

	input_dev->evbit[0] = BIT_MASK(EV_KEY) ;

	platform_set_drvdata(pdev, AD_button);

	ADCInit();
	prockAD_button=AD_button;

	/* Register the input device */
	error = input_register_device(input_dev);
	if (error) {
		dev_err(&pdev->dev, "failed to register input device\n");
		goto failed2;
	}

	setup_timer(&AD_button->timer, rk28_adkeyscan_timer, (unsigned long)AD_button);
	//mod_timer(&AD_button->timer, 100);
	AD_button->timer.expires  = jiffies + 3;
	add_timer(&AD_button->timer);
 #if defined(CONFIG_BOARD_NX7005)   
       GPIOSetPinDirection(GPIOPortB_Pin4,GPIO_IN);
       GPIOSetPinDirection(GPIOPortB_Pin5,GPIO_IN);
       GPIOSetPinDirection(GPIOPortB_Pin6,GPIO_IN);
       GPIOSetPinDirection(GPIOPortB_Pin7,GPIO_IN);
 #endif
#ifdef CONFIG_MACH_RK2808SDK
        error = request_gpio_irq(WAKEUP_KEY_PORT,rk28_AD_irq_handler,GPIOEdgelFalling,NULL);
	if(error)
	{
		printk("unable to request recover key IRQ\n");
		goto failed2;
	}	
#endif        

#ifdef CONFIG_MACH_PWS700AA
    error = request_gpio_irq(GPIOPortE_Pin3,rk28_AD_irq_handler,GPIOEdgelRising,NULL);
    GPIOPullUpDown(GPIOPortE_Pin3,GPIOPullDown);    
	if(error)
	{
		printk("unable to request recover key IRQ\n");
		goto failed2;
	}	
#endif        

	return 0;

failed2:
	input_unregister_device(AD_button->input_dev);
	platform_set_drvdata(pdev, NULL);	
failed1:
	input_free_device(input_dev);
	kfree(AD_button);
	return error;
}
コード例 #11
0
ファイル: max8997_haptic.c プロジェクト: kongzizaixian/kernel
static int max8997_haptic_probe(struct platform_device *pdev)
{
    struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
    const struct max8997_platform_data *pdata =
        dev_get_platdata(iodev->dev);
    const struct max8997_haptic_platform_data *haptic_pdata = NULL;
    struct max8997_haptic *chip;
    struct input_dev *input_dev;
    int error;

    if (pdata)
        haptic_pdata = pdata->haptic_pdata;

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

    chip = kzalloc(sizeof(struct max8997_haptic), GFP_KERNEL);
    input_dev = input_allocate_device();
    if (!chip || !input_dev) {
        dev_err(&pdev->dev, "unable to allocate memory\n");
        error = -ENOMEM;
        goto err_free_mem;
    }

    INIT_WORK(&chip->work, max8997_haptic_play_effect_work);
    mutex_init(&chip->mutex);

    chip->client = iodev->haptic;
    chip->dev = &pdev->dev;
    chip->input_dev = input_dev;
    chip->pwm_period = haptic_pdata->pwm_period;
    chip->type = haptic_pdata->type;
    chip->mode = haptic_pdata->mode;
    chip->pwm_divisor = haptic_pdata->pwm_divisor;

    switch (chip->mode) {
    case MAX8997_INTERNAL_MODE:
        chip->internal_mode_pattern =
            haptic_pdata->internal_mode_pattern;
        chip->pattern_cycle = haptic_pdata->pattern_cycle;
        chip->pattern_signal_period =
            haptic_pdata->pattern_signal_period;
        break;

    case MAX8997_EXTERNAL_MODE:
        chip->pwm = pwm_request(haptic_pdata->pwm_channel_id,
                                "max8997-haptic");
        if (IS_ERR(chip->pwm)) {
            error = PTR_ERR(chip->pwm);
            dev_err(&pdev->dev,
                    "unable to request PWM for haptic, error: %d\n",
                    error);
            goto err_free_mem;
        }
        break;

    default:
        dev_err(&pdev->dev,
                "Invalid chip mode specified (%d)\n", chip->mode);
        error = -EINVAL;
        goto err_free_mem;
    }

    chip->regulator = regulator_get(&pdev->dev, "inmotor");
    if (IS_ERR(chip->regulator)) {
        error = PTR_ERR(chip->regulator);
        dev_err(&pdev->dev,
                "unable to get regulator, error: %d\n",
                error);
        goto err_free_pwm;
    }

    input_dev->name = "max8997-haptic";
    input_dev->id.version = 1;
    input_dev->dev.parent = &pdev->dev;
    input_dev->close = max8997_haptic_close;
    input_set_drvdata(input_dev, chip);
    input_set_capability(input_dev, EV_FF, FF_RUMBLE);

    error = input_ff_create_memless(input_dev, NULL,
                                    max8997_haptic_play_effect);
    if (error) {
        dev_err(&pdev->dev,
                "unable to create FF device, error: %d\n",
                error);
        goto err_put_regulator;
    }

    error = input_register_device(input_dev);
    if (error) {
        dev_err(&pdev->dev,
                "unable to register input device, error: %d\n",
                error);
        goto err_destroy_ff;
    }

    platform_set_drvdata(pdev, chip);
    return 0;

err_destroy_ff:
    input_ff_destroy(input_dev);
err_put_regulator:
    regulator_put(chip->regulator);
err_free_pwm:
    if (chip->mode == MAX8997_EXTERNAL_MODE)
        pwm_free(chip->pwm);
err_free_mem:
    input_free_device(input_dev);
    kfree(chip);

    return error;
}
コード例 #12
0
static int wacom_i2c_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	struct wacom_i2c *wac_i2c;
	struct wacom_g5_platform_data *pdata = client->dev.platform_data;
	int i, ret;
	i = ret = 0;

	printk(KERN_ERR "[E-PEN]:%s:\n", __func__);

	/*Check I2C functionality*/
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		goto err3;

	/*Obtain kernel memory space for wacom i2c*/
	wac_i2c = kzalloc(sizeof(struct wacom_i2c), GFP_KERNEL);
	if (wac_i2c == NULL) goto fail;
	wac_i2c->wac_feature = &wacom_feature_EMR;

	pdata->init_platform_hw();


	/*Initializing for semaphor*/
	mutex_init(&wac_i2c->lock);

	/*Register platform data*/
	wac_i2c->wac_pdata = client->dev.platform_data;

	/*Register callbacks*/
	wac_i2c->callbacks.check_prox = wacom_check_emr_prox;
	if (wac_i2c->wac_pdata->register_cb)
		wac_i2c->wac_pdata->register_cb(&wac_i2c->callbacks);

	/*Register wacom i2c to input device*/
	wac_i2c->input_dev = input_allocate_device();
	if (wac_i2c == NULL || wac_i2c->input_dev == NULL)
		goto fail;
	wacom_i2c_set_input_values(client, wac_i2c, wac_i2c->input_dev);

	wac_i2c->client = client;
	wac_i2c->irq = client->irq;
#ifdef WACOM_PDCT_WORK_AROUND
	wac_i2c->irq_pdct = gpio_to_irq(pdata->gpio_pendct);
#endif

	/*Change below if irq is needed*/
	wac_i2c->irq_flag = 1;

#ifdef CONFIG_HAS_EARLYSUSPEND
		wac_i2c->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
		wac_i2c->early_suspend.suspend = wacom_i2c_early_suspend;
		wac_i2c->early_suspend.resume = wacom_i2c_late_resume;
		register_early_suspend(&wac_i2c->early_suspend);
#endif

	/*Init Featreus by hw rev*/
#if defined(CONFIG_USA_MODEL_SGH_I717)
		if( get_hw_rev() == 0x01 ) {
			printk("[E-PEN] Wacom driver is working for 4.4mm pitch pad.\n");
			/* Firmware Feature */
			Firmware_version_of_file = 0x340;
			Binary = (unsigned char*)Binary_44;		
		}		
		else if( get_hw_rev() >= HWREV_PEN_PITCH4P4 ) {
			printk("[E-PEN] Wacom driver is working for 4.4mm pitch pad.\n");
			/* Firmware Feature */
			Firmware_version_of_file = Firmware_version_of_file_44;
			Binary = (unsigned char*)Binary_44;
		}
		
#else

	if( get_hw_rev() >= HWREV_PEN_PITCH4P4 ) {
		printk("[E-PEN] Wacom driver is working for 4.4mm pitch pad.\n");

		/* Firmware Feature */
		Firmware_version_of_file = Firmware_version_of_file_44;
		Binary = (unsigned char*)Binary_44;
	}
	else {
		printk("[E-PEN] Wacom driver is working for 4.8mm pitch pad.\n");

		/* Firmware Feature */
		Firmware_version_of_file = Firmware_version_of_file_48;
		Binary = (unsigned char*)Binary_48;
	}
#endif


	init_offset_tables();
	INIT_WORK(&wac_i2c->update_work, update_work_func);
	INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work);

	/* Reset IC */
	gpio_set_value(GPIO_PEN_RESET, 0);
	msleep(120);
	gpio_set_value(GPIO_PEN_RESET, 1);
	msleep(15);
	ret = wacom_i2c_query(wac_i2c);

	if( ret < 0 )
		epen_reset_result = false;
	else
		epen_reset_result = true;

	input_set_abs_params(wac_i2c->input_dev, ABS_X, pdata->min_x,
		pdata->max_x, 4, 0);
	input_set_abs_params(wac_i2c->input_dev, ABS_Y, pdata->min_y,
		pdata->max_y, 4, 0);
	input_set_abs_params(wac_i2c->input_dev, ABS_PRESSURE, pdata->min_pressure,
		pdata->max_pressure, 0, 0);
	input_set_drvdata(wac_i2c->input_dev, wac_i2c);

	/*Set client data*/
	i2c_set_clientdata(client, wac_i2c);

	/*Before registering input device, data in each input_dev must be set*/
	if (input_register_device(wac_i2c->input_dev))
		goto err2;

	g_client = client;

	/*  if(wac_i2c->irq_flag) */
	/*   disable_irq(wac_i2c->irq); */

	sec_epen= device_create(sec_class, NULL, 0, NULL, "sec_epen");
	dev_set_drvdata(sec_epen, wac_i2c);

	if (IS_ERR(sec_epen))
			printk(KERN_ERR "Failed to create device(sec_epen)!\n");

	if (device_create_file(sec_epen, &dev_attr_epen_firm_update)< 0)
			printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_firm_update.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_firm_update_status)< 0)
			printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_firm_update_status.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_firm_version)< 0)
			printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_firm_version.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_rotation)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_rotation.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_hand)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_hand.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_reset)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_reset.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_reset_result)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_reset_result.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_checksum)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_checksum.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_checksum_result)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_checksum_result.attr.name);
	

	if (device_create_file(sec_epen, &dev_attr_set_epen_module_off) < 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_set_epen_module_off.attr.name);

	if (device_create_file(sec_epen, &dev_attr_set_epen_module_on) < 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_set_epen_module_on.attr.name);


	
	/*Request IRQ*/
	if (wac_i2c->irq_flag) {
		ret = request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt, IRQF_DISABLED|IRQF_TRIGGER_RISING|IRQF_ONESHOT, wac_i2c->name, wac_i2c);
		if (ret < 0)
			goto err1;
	}

#if defined(WACOM_PDCT_WORK_AROUND)
		ret =
			request_threaded_irq(wac_i2c->irq_pdct, NULL,
					wacom_interrupt_pdct,
					IRQF_DISABLED | IRQF_TRIGGER_RISING |
					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
					wac_i2c->name, wac_i2c);
		if (ret < 0) {
			printk(KERN_ERR
				"[E-PEN]: failed to request irq(%d) - %d\n",
				wac_i2c->irq_pdct, ret);
			goto err1;
		}
#endif
	/* firmware update */
	printk(KERN_NOTICE "[E-PEN] wacom fw ver : 0x%x, new fw ver : 0x%x\n",
		wac_i2c->wac_feature->fw_version, Firmware_version_of_file);
	if( wac_i2c->wac_feature->fw_version < Firmware_version_of_file ) 
	{
		#if defined(CONFIG_KOR_MODEL_SHV_E160S) || defined(CONFIG_KOR_MODEL_SHV_E160K) || defined(CONFIG_KOR_MODEL_SHV_E160L) || defined (CONFIG_JPN_MODEL_SC_05D)
		printk("[E-PEN] %s\n", __func__);
		
		disable_irq(wac_i2c->irq);
		
		printk(KERN_NOTICE "[E-PEN]: INIT_FIRMWARE_FLASH is enabled.\n");
		ret = wacom_i2c_flash(wac_i2c);
		msleep(800);
		printk(KERN_ERR "[E-PEN]: flashed.(%d)\n", ret);
		
		wacom_i2c_query(wac_i2c);
		
		enable_irq(wac_i2c->irq);
		#else
		schedule_work(&wac_i2c->update_work);
		#endif
	}
	
	/* To send exact checksum data at sleep state ... Xtopher */
	printk(KERN_ERR"[E-PEN]: Verify CHECKSUM.\n");
	epen_checksum_read_atBoot(wac_i2c);
	msleep(20);

	return 0;

err3:
	printk(KERN_ERR "[E-PEN]: No I2C functionality found\n");
	return -ENODEV;

err2:
	printk(KERN_ERR "[E-PEN]: err2 occured\n");
	input_free_device(wac_i2c->input_dev);
	return -EIO;

err1:
	printk(KERN_ERR "[E-PEN]: err1 occured(num:%d)\n", ret);
	input_free_device(wac_i2c->input_dev);
	wac_i2c->input_dev = NULL;
	return -EIO;

fail:
	printk(KERN_ERR "[E-PEN]: fail occured\n");
	return -ENOMEM;
}
コード例 #13
0
ファイル: twl4030-vibra.c プロジェクト: Aircell/asp-kernel
static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
{
   struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data;
   struct vibra_info *info;
   int ret;

   if (!pdata) {
       dev_dbg(&pdev->dev, "platform_data not available\n");
       return -EINVAL;
   }

   info = kzalloc(sizeof(*info), GFP_KERNEL);
   if (!info)
       return -ENOMEM;

   info->dev = &pdev->dev;
   info->coexist = pdata->coexist;
   INIT_WORK(&info->play_work, vibra_play_work);

   info->input_dev = input_allocate_device();
   if (info->input_dev == NULL) {
       dev_err(&pdev->dev, "couldn't allocate input device\n");
       ret = -ENOMEM;
       goto err_kzalloc;
   }

   input_set_drvdata(info->input_dev, info);

   info->input_dev->name = "twl4030:vibrator";
   info->input_dev->id.version = 1;
   info->input_dev->dev.parent = pdev->dev.parent;
   info->input_dev->open = twl4030_vibra_open;
   info->input_dev->close = twl4030_vibra_close;
   __set_bit(FF_RUMBLE, info->input_dev->ffbit);

   ret = input_ff_create_memless(info->input_dev, NULL, vibra_play);
   if (ret < 0) {
       dev_dbg(&pdev->dev, "couldn't register vibrator to FF\n");
       goto err_ialloc;
   }

   ret = input_register_device(info->input_dev);
   if (ret < 0) {
       dev_dbg(&pdev->dev, "couldn't register input device\n");
       goto err_iff;
   }

   vibra_disable_leds();

   platform_set_drvdata(pdev, info);
#ifdef VDEBUG
printk(KERN_INFO "successfully probed the vibrator device.\n");
#endif
   return 0;

err_iff:
   input_ff_destroy(info->input_dev);
err_ialloc:
   input_free_device(info->input_dev);
err_kzalloc:
   kfree(info);
   return ret;
}
コード例 #14
0
ファイル: kbtab.c プロジェクト: CSCLOG/beaglebone
static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct usb_endpoint_descriptor *endpoint;
	struct kbtab *kbtab;
	struct input_dev *input_dev;
	int error = -ENOMEM;

	kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!kbtab || !input_dev)
		goto fail1;

	kbtab->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &kbtab->data_dma);
	if (!kbtab->data)
		goto fail1;

	kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
	if (!kbtab->irq)
		goto fail2;

	kbtab->usbdev = dev;
	kbtab->dev = input_dev;

	usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
	strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));

	input_dev->name = "KB Gear Tablet";
	input_dev->phys = kbtab->phys;
	usb_to_input_id(dev, &input_dev->id);
	input_dev->dev.parent = &intf->dev;

	input_set_drvdata(input_dev, kbtab);

	input_dev->open = kbtab_open;
	input_dev->close = kbtab_close;

	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	input_dev->keybit[BIT_WORD(BTN_LEFT)] |=
		BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
	input_dev->keybit[BIT_WORD(BTN_DIGI)] |=
		BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_TOUCH);
	input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
	input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0);
	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);

	endpoint = &intf->cur_altsetting->endpoint[0].desc;

	usb_fill_int_urb(kbtab->irq, dev,
			 usb_rcvintpipe(dev, endpoint->bEndpointAddress),
			 kbtab->data, 8,
			 kbtab_irq, kbtab, endpoint->bInterval);
	kbtab->irq->transfer_dma = kbtab->data_dma;
	kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	error = input_register_device(kbtab->dev);
	if (error)
		goto fail3;

	usb_set_intfdata(intf, kbtab);

	return 0;

 fail3:	usb_free_urb(kbtab->irq);
 fail2:	usb_free_coherent(dev, 8, kbtab->data, kbtab->data_dma);
 fail1:	input_free_device(input_dev);
	kfree(kbtab);
	return error;
}
コード例 #15
0
ファイル: pxa27x_keyboard.c プロジェクト: 3sOx/asuswrt-merlin
static int __devinit pxakbd_probe(struct platform_device *pdev)
{
	struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data;
	struct input_dev *input_dev;
	int i, row, col, error;

	/* Create and register the input driver. */
	input_dev = input_allocate_device();
	if (!input_dev) {
		printk(KERN_ERR "Cannot request keypad device\n");
		return -ENOMEM;
	}

	input_dev->name = DRIVER_NAME;
	input_dev->id.bustype = BUS_HOST;
	input_dev->open = pxakbd_open;
	input_dev->close = pxakbd_close;
	input_dev->dev.parent = &pdev->dev;

	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
	input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL);
	for (row = 0; row < pdata->nr_rows; row++) {
		for (col = 0; col < pdata->nr_cols; col++) {
			int code = pdata->keycodes[row][col];
			if (code > 0)
				set_bit(code, input_dev->keybit);
		}
	}

	error = request_irq(IRQ_KEYPAD, pxakbd_irq_handler, IRQF_DISABLED,
			    DRIVER_NAME, pdev);
	if (error) {
		printk(KERN_ERR "Cannot request keypad IRQ\n");
		pxa_set_cken(CKEN_KEYPAD, 0);
		goto err_free_dev;
	}

	platform_set_drvdata(pdev, input_dev);

	/* Register the input device */
	error = input_register_device(input_dev);
	if (error)
		goto err_free_irq;

	/* Setup GPIOs. */
	for (i = 0; i < pdata->nr_rows + pdata->nr_cols; i++)
		pxa_gpio_mode(pdata->gpio_modes[i]);

	/*
	 * Store rows/cols info into keyboard registers.
	 */

	KPC |= (pdata->nr_rows - 1) << 26;
	KPC |= (pdata->nr_cols - 1) << 23;

	for (col = 0; col < pdata->nr_cols; col++)
		KPC |= KPC_MS0 << col;

	return 0;

 err_free_irq:
	platform_set_drvdata(pdev, NULL);
	free_irq(IRQ_KEYPAD, pdev);
 err_free_dev:
	input_free_device(input_dev);
	return error;
}
コード例 #16
0
/*
 * h3600ts_connect() is the routine that is called when someone adds a
 * new serio device that supports H3600 protocol and registers it as
 * an input device.
 */
static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
{
	struct h3600_dev *ts;
	struct input_dev *input_dev;
	int err;

	ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!ts || !input_dev) {
		err = -ENOMEM;
		goto fail1;
	}

	ts->serio = serio;
	ts->dev = input_dev;
	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", serio->phys);

	input_dev->name = "H3600 TouchScreen";
	input_dev->phys = ts->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->id.vendor = SERIO_H3600;
	input_dev->id.product = 0x0666;  /* FIXME !!! We can ask the hardware */
	input_dev->id.version = 0x0100;
	input_dev->dev.parent = &serio->dev;

	input_set_drvdata(input_dev, ts);

	input_dev->event = h3600ts_event;

	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
		BIT_MASK(EV_LED) | BIT_MASK(EV_PWR);
	input_dev->ledbit[0] = BIT_MASK(LED_SLEEP);
	input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0);
	input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0);

	set_bit(KEY_RECORD, input_dev->keybit);
	set_bit(KEY_Q, input_dev->keybit);
	set_bit(KEY_PROG1, input_dev->keybit);
	set_bit(KEY_PROG2, input_dev->keybit);
	set_bit(KEY_PROG3, input_dev->keybit);
	set_bit(KEY_UP, input_dev->keybit);
	set_bit(KEY_RIGHT, input_dev->keybit);
	set_bit(KEY_LEFT, input_dev->keybit);
	set_bit(KEY_DOWN, input_dev->keybit);
	set_bit(KEY_ENTER, input_dev->keybit);
	set_bit(KEY_SUSPEND, input_dev->keybit);
	set_bit(BTN_TOUCH, input_dev->keybit);

	/* Device specific stuff */
	set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
	set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);

	if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
			IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) {
		printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
		err = -EBUSY;
		goto fail2;
	}

	if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
			IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) {
		printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
		err = -EBUSY;
		goto fail3;
	}

	serio_set_drvdata(serio, ts);

	err = serio_open(serio, drv);
	if (err)
		return err;

	//h3600_flite_control(1, 25);     /* default brightness */
	input_register_device(ts->dev);

	return 0;

fail3:	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
fail2:	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
fail1:	serio_set_drvdata(serio, NULL);
	input_free_device(input_dev);
	kfree(ts);
	return err;
}
コード例 #17
0
static int trout_h2w_probe(struct platform_device *pdev)
{
	int ret;
	struct h2w_platform_data *pdata = pdev->dev.platform_data; /* FIH-SW2-MM-AY-TAP_headset_00 */

	printk(KERN_INFO "[AUD_HS]: Registering H2W (headset) driver\n");

	H2W_DBG("");
	
	hi = kzalloc(sizeof(struct h2w_info), GFP_KERNEL);
	
	if (!hi)
		return -ENOMEM;

  /*                                                        
   * 1. Headset insertion/removal causes UEvent's to be sent
   * 2. /sys/class/switch/headset_sensor/state to be updated 
   * 3. debounce time too short will affect the behavior of headset plugin/out in phone call
   */
   
    atomic_set(&hi->hs_state, 0);
	atomic_set(&hi->btn_state, 0);  
	
	hi->ignore_btn        = 0;
	/* FIH-SW2-MM-AY-TAP_headset_00 [ */
	hi->cable_in1 = pdata->cable_in1;
	hi->cable_in2 = pdata->cable_in2;
	/* FIH-SW2-MM-AY-TAP_headset_00 ] */
	/* MM-RC-TAP reduce delay time after removing headset  1206 */
/* MM-NC-Headset_Debounce_Time-00-[+ */
	hi->debounce_time     = ktime_set(0, 800000000);  /* 200 -> 800 ms */
/* MM-NC-Headset_Debounce_Time-00-]- */
	hi->btn_debounce_time = ktime_set(0,  80000000);  /*  80 ms */   
	hi->sdev.name         = "headset_sensor";
	hi->sdev.print_name   = trout_h2w_print_name;	
	hi->hs_input          = input_allocate_device();
	
	if (!hi->hs_input) {
		ret = -ENOMEM;
		goto err_request_input_dev;
	}	
	
  	hi->hs_input->name = "fih_ringswitch";
	
 	set_bit(EV_KEY, hi->hs_input->evbit);  	  
  	//set_bit(KEY_RINGSWITCH, hi->hs_input->keybit);

	ret = input_register_device(hi->hs_input);
	
	if (ret < 0)
	    goto err_register_hs_input_dev;	  

	ret = switch_dev_register(&hi->sdev);
	
	if (ret < 0)
		goto err_switch_dev_register;

	g_detection_work_queue = create_workqueue("detection");
	
	if (g_detection_work_queue == NULL) {
		ret = -ENOMEM;
		goto err_create_work_queue;
	}

	ret = gpio_request(hi->cable_in1, "h2w_detect"); /* FIH-SW2-MM-AY-TAP_headset_00 */
	
	if (ret < 0)
		goto err_request_detect_gpio;

	ret = gpio_direction_input(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */

	if (ret < 0)
		goto err_set_detect_gpio;
    else
        H2W_DBG(" set aid gpio(%d) as input pin : success.\r\n", hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */

    hi->irq = gpio_to_irq(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */
	
    if (hi->irq < 0) { /* FIH-SW3-MM-AY-GUA Coverity 1108 */
	    ret = hi->irq;
  	    goto err_get_h2w_detect_irq_num_failed;
    }
    else
	    H2W_DBG(" hs_det gpio_to_irq(%d): success.\r\n", hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */

	hrtimer_init(&hi->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	
	hi->timer.function = detect_event_timer_func;	

#ifdef FEATURE_AUD_HOOK_BTN
	ret = gpio_request(hi->cable_in2, "h2w_button"); /* FIH-SW2-MM-AY-TAP_headset_00 */

	if (ret < 0)
		goto err_request_button_gpio;

	ret = gpio_direction_input(hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */
	
	if (ret < 0)
		goto err_set_button_gpio;
    else
        H2W_DBG(" set ptt gpio(%d) as input pin : success.\r\n", hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */

	hi->irq_btn = gpio_to_irq(hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */
	
	if (hi->irq_btn < 0) { /* FIH-SW3-MM-AY-GUA Coverity 1108 */
		ret = hi->irq_btn;
		goto err_get_button_irq_num_failed;
	}
    else
        H2W_DBG(" hook_btn gpio_to_irq(%d): success.\r\n", hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */

	hrtimer_init(&hi->btn_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	
	hi->btn_timer.function = button_event_timer_func;
#endif

	aud_hs_print_gpio(); 

    //headset inserted : gpio H->L(detect LOW level)
	ret = request_irq(hi->irq, detect_irq_handler,
	         IRQF_TRIGGER_HS_INSERTED, "h2w_detect", NULL);

	if (ret < 0)
		goto err_request_detect_irq;
    else
        H2W_DBG(" request_irq (gpio %d, IRQF_TRIGGER_LOW) success\n", hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */

    // Set headset_detect pin as wake up pin
    ret = irq_set_irq_wake(hi->irq, 1);

if (ret < 0)
	goto err_request_input_dev;

#ifdef FEATURE_AUD_HOOK_BTN
	// Disable button until plugged in 
	set_irq_flags(hi->irq_btn, IRQF_VALID | IRQF_NOAUTOEN);

	ret = request_irq(hi->irq_btn, button_irq_handler,
			  IRQF_TRIGGER_BTN_PRESSED, "h2w_button", NULL);         
	
	if (ret < 0)
		goto err_request_h2w_headset_button_irq;
    else
        H2W_DBG("request_irq (gpio %d, IRQF_TRIGGER_HIGH) success\n", hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */

#endif
	
	hi->input = input_allocate_device();

	if (!hi->input) {
		ret = -ENOMEM;
		goto err_request_input_dev;
	}

	hi->input->name                        = "simple_remote_appkey";/* MM-SC-LIVEKEY-DETECT  //"fih_headsethook";*/
	/* MM-RC-HEADSET-MULTIBUTTON-DETECT[* */
	//hi->input->evbit[0]                    = BIT_MASK(EV_KEY); 
    //hi->input->keybit[BIT_WORD(KEY_MEDIA)] = BIT_MASK(KEY_MEDIA); 
	if (isCTIAheadset) { /* FIH-SW2-MM-AY-hsed_type-03 */
		input_set_capability(hi->input, EV_KEY, KEY_VOLUMEDOWN);
		input_set_capability(hi->input, EV_KEY, KEY_VOLUMEUP);
		input_set_capability(hi->input, EV_KEY, BTN_3);  /* MM-RC-HEADSET-LiveKEY-DETECT+ */
	}
	input_set_capability(hi->input, EV_KEY, KEY_MEDIA);
	/* MM-RC-HEADSET-MULTIBUTTON-DETECT]* */

	ret = input_register_device(hi->input);
	
	if (ret < 0)
		goto err_register_input_dev;


	return 0;

// Error Messages
err_register_input_dev:
    printk(KERN_ERR "aud_hs: err_register_input_dev\n");
	input_free_device(hi->input);

err_register_hs_input_dev:
    printk(KERN_ERR "aud_hs: err_register_hs_input_dev\n");
	input_free_device(hi->hs_input);
err_request_input_dev:
    #ifdef FEATURE_AUD_HOOK_BTN
    printk(KERN_ERR "aud_hs: err_request_input_dev\n");
	free_irq(hi->irq_btn, 0);
    #endif    
#ifdef FEATURE_AUD_HOOK_BTN		
err_request_h2w_headset_button_irq:
    printk(KERN_ERR "aud_hs: request_h2w_headset_button_irq\n");
	free_irq(hi->irq, 0);
#endif	
err_request_detect_irq:
#ifdef FEATURE_AUD_HOOK_BTN		
err_get_button_irq_num_failed:
#endif
err_get_h2w_detect_irq_num_failed:
#ifdef FEATURE_AUD_HOOK_BTN	
err_set_button_gpio:
#endif
err_set_detect_gpio:
    printk(KERN_ERR "aud_hs: AUD_PIN_HOOK_BTN, gpio/irq error\n");
    #ifdef FEATURE_AUD_HOOK_BTN
	gpio_free(hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */
    #endif
#ifdef FEATURE_AUD_HOOK_BTN	
err_request_button_gpio:
    printk(KERN_ERR "aud_hs: err_request_button_gpio\n");
	gpio_free(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */
#endif	
err_request_detect_gpio:
      printk(KERN_ERR "aud_hs: err_request_detect_gpio\n");
	destroy_workqueue(g_detection_work_queue);
err_create_work_queue:
      printk(KERN_ERR "aud_hs: err_create_work_queue\n");    
	switch_dev_unregister(&hi->sdev);
err_switch_dev_register:
	printk(KERN_ERR "aud_hs: Failed to register driver\n");

	return ret;
}
コード例 #18
0
static int lge_hsd_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct max1462x_platform_data *pdata = pdev->dev.platform_data;


	struct hsd_info *hi;

	HSD_DBG("lge_hsd_probe\n");

	hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL);

	if ( hi == NULL) {
		HSD_ERR("Failed to allloate headset per device info\n");
		return -ENOMEM;
	}

	if(pdev->dev.of_node){
		pdata = devm_kzalloc(&pdev->dev,sizeof(struct max1462x_platform_data),GFP_KERNEL);
		if(!pdata){
			HSD_ERR("Failed to allocate memory\n");
			return -ENOMEM;
		}
		pdev->dev.platform_data = pdata;

		max1462x_parse_dt(&pdev->dev,pdata);
	} else {
		pdata = devm_kzalloc(&pdev->dev,sizeof(struct max1462x_platform_data),GFP_KERNEL);
		if(!pdata){
			HSD_ERR("Failed to allocate memory\n");
			return -ENOMEM;
		}
		else
			pdata = pdev->dev.platform_data;
	}
	hi->key_code = pdata->key_code;

	platform_set_drvdata(pdev, hi);

	atomic_set(&hi->btn_state, 0);
	atomic_set(&hi->is_3_pole_or_not, 1);
	atomic_set(&hi->irq_key_enabled, FALSE);

	hi->gpio_mic_en = pdata->gpio_mic_en;
	hi->gpio_detect = pdata->gpio_detect;
	hi->gpio_key = pdata->gpio_key;
	hi->gpio_set_value_func = pdata->gpio_set_value_func;
	hi->gpio_get_value_func = pdata->gpio_get_value_func;
#ifdef CONFIG_SWITCH_MAX1462X_WA
	hi->latency_for_key = msecs_to_jiffies(80);
#else
	hi->latency_for_key = msecs_to_jiffies(50); /* convert milli to jiffies */
#endif
	mutex_init(&hi->mutex_lock);
	INIT_WORK(&hi->work, detect_work);
	INIT_DELAYED_WORK(&hi->work_for_key_pressed, button_pressed);
	INIT_DELAYED_WORK(&hi->work_for_key_released, button_released);

	ret = gpio_request(hi->gpio_mic_en, "gpio_mic_en");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_request\n", hi->gpio_mic_en);
		goto error_02;
	}

	ret = gpio_direction_output(hi->gpio_mic_en, 0);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_direction_input\n", hi->gpio_mic_en);
		goto error_02;
	}
	HSD_DBG("gpio_get_value_cansleep(hi->gpio_mic_en) = %d\n", gpio_get_value_cansleep(hi->gpio_mic_en));

	/* init gpio_detect */
	ret = gpio_request(hi->gpio_detect, "gpio_detect");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_request\n", hi->gpio_detect);
		goto error_03;
	}

	ret = gpio_direction_input(hi->gpio_detect);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_direction_input\n", hi->gpio_detect);
		goto error_03;
	}

	/*init gpio_key */
	ret = gpio_request(hi->gpio_key, "gpio_key");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_request\n", hi->gpio_key);
		goto error_04;
	}

	ret = gpio_direction_input(hi->gpio_key);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_direction_input\n", hi->gpio_key);
		goto error_04;
	}


	/* initialize irq of gpio_key */
	hi->irq_key = gpio_to_irq(hi->gpio_key);

	HSD_DBG("hi->irq_key = %d\n", hi->irq_key);

	if (hi->irq_key < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_key;
		goto error_06;
	}
	ret = request_threaded_irq(hi->irq_key, NULL, button_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, hi);
	if (ret) {
		HSD_ERR("failed to request button irq\n");
		goto error_06;
	}

	ret = irq_set_irq_wake(hi->irq_key, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set irq_key interrupt wake\n");
		goto error_06;
	}

	hi->irq_detect = gpio_to_irq(hi->gpio_detect);
	HSD_DBG("hi->irq_detect = %d\n", hi->irq_detect);

	if (hi->irq_detect < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_detect;
		goto error_07;
	}
	ret = request_threaded_irq(hi->irq_detect, NULL, earjack_det_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, hi);

	if (ret) {
		HSD_ERR("failed to request button irq\n");
		goto error_07;
	}

	ret = irq_set_irq_wake(hi->irq_detect, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set gpio_detect interrupt wake\n");
		goto error_07;
	}
	/* initialize switch device */
	hi->sdev.name = pdata->switch_name;
	hi->sdev.print_state = lge_hsd_print_state;
	hi->sdev.print_name = lge_hsd_print_name;

	ret = switch_dev_register(&hi->sdev);
	if (ret < 0) {
		HSD_ERR("Failed to register switch device\n");
		goto error_08;
	}

	/* initialize input device */
	hi->input = input_allocate_device();
	if (!hi->input) {
		HSD_ERR("Failed to allocate input device\n");
		ret = -ENOMEM;
		goto error_09;
	}

	hi->input->name = pdata->keypad_name;

	hi->input->id.vendor    = 0x0001;
	hi->input->id.product   = 1;
	hi->input->id.version   = 1;

	/* headset tx noise */
	{
		struct qpnp_vadc_result result;
		int acc_read_value = 0;
		int i, rc = 0;
		int count = 3;

		for (i = 0; i < count; i++)
		{
/* LIMIT: Include ONLY A1, B1, Vu3, Z models used MSM8974 AA/AB */
#ifdef CONFIG_ADC_READY_CHECK_JB
			rc = qpnp_vadc_read_lge(P_MUX6_1_1,&result);
#else
			/* MUST BE IMPLEMENT :
			 * After MSM8974 AC and later version(PMIC combination change),
			 * ADC AMUX of PMICs are separated in each dual PMIC.
			 *
			 * Ref.
			 * qpnp-adc-voltage.c : *qpnp_get_vadc(), qpnp_vadc_read().
			 * qpnp-charger.c     : new implementation by QCT.
			 */
#endif
			if (rc < 0)
			{
				if (rc == -ETIMEDOUT) {
					pr_err("[DEBUG]adc read timeout \n");
				} else {
					pr_err("[DEBUG]adc read error - %d\n", rc);
				}
			}
			else
			{
				acc_read_value = (int)result.physical;
				pr_info("%s: acc_read_value - %d\n", __func__, (int)result.physical);
				break;
			}
		}
	}
	set_bit(EV_SYN, hi->input->evbit);
	set_bit(EV_KEY, hi->input->evbit);
	set_bit(EV_SW, hi->input->evbit);
	set_bit(hi->key_code, hi->input->keybit);
	set_bit(SW_HEADPHONE_INSERT, hi->input->swbit);
	set_bit(SW_MICROPHONE_INSERT, hi->input->swbit);
	input_set_capability(hi->input, EV_KEY, KEY_MEDIA);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEDOWN);
	ret = input_register_device(hi->input);
	if (ret) {
		HSD_ERR("Failed to register input device\n");
		goto error_09;
	}

	if (!(hi->gpio_get_value_func(hi->gpio_detect)))

#ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE
		/* to detect in initialization with eacjack insertion */
		queue_work(local_max1462x_workqueue, &(hi->work));
#else
	/* to detect in initialization with eacjack insertion */
	schedule_work(&(hi->work));
#endif
	return ret;

error_09:
	input_free_device(hi->input);
error_08:
	switch_dev_unregister(&hi->sdev);
error_07:
	free_irq(hi->irq_detect, 0);
error_06:
	free_irq(hi->irq_key, 0);
error_04:
	gpio_free(hi->gpio_key);
error_03:
	gpio_free(hi->gpio_detect);
error_02:
	gpio_free(hi->gpio_mic_en);
	kfree(hi);
	return ret;
}
コード例 #19
0
ファイル: gpio_event.c プロジェクト: Yannicked/htc-m7
static int gpio_event_probe(struct platform_device *pdev)
{
	int err;
	struct gpio_event *ip;
	struct gpio_event_platform_data *event_info;
	int dev_count = 1;
	int i;
	int registered = 0;

	event_info = pdev->dev.platform_data;
	if (event_info == NULL) {
		KEY_LOGE("KEY_ERR: %s: No pdata\n", __func__);
		return -ENODEV;
	}
	if ((!event_info->name && !event_info->names[0]) ||
	    !event_info->info || !event_info->info_count) {
		KEY_LOGE("KEY_ERR: %s: Incomplete pdata\n", __func__);
		return -ENODEV;
	}
	if (!event_info->name)
		while (event_info->names[dev_count])
			dev_count++;
	ip = kzalloc(sizeof(*ip) +
		     sizeof(ip->state[0]) * event_info->info_count +
		     sizeof(*ip->input_devs) +
		     sizeof(ip->input_devs->dev[0]) * dev_count, GFP_KERNEL);
	if (ip == NULL) {
		err = -ENOMEM;
		KEY_LOGE("KEY_ERR: %s: Failed to allocate private data\n", __func__);
		goto err_kp_alloc_failed;
	}
	ip->input_devs = (void*)&ip->state[event_info->info_count];
	platform_set_drvdata(pdev, ip);

	for (i = 0; i < dev_count; i++) {
		struct input_dev *input_dev = input_allocate_device();
		if (input_dev == NULL) {
			err = -ENOMEM;
			KEY_LOGE("KEY_ERR: %s: "
				"Failed to allocate input device\n", __func__);
			goto err_input_dev_alloc_failed;
		}
		input_set_drvdata(input_dev, ip);
		input_dev->name = event_info->name ?
					event_info->name : event_info->names[i];
		input_dev->event = gpio_input_event;
		ip->input_devs->dev[i] = input_dev;
#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_SWEEP2WAKE
		if (!strcmp(input_dev->name, "keypad_8960")) {
			sweep2wake_setdev(input_dev);
			printk(KERN_INFO "[sweep2wake]: set device %s\n", input_dev->name);
		}
#endif
	}
	ip->input_devs->count = dev_count;
	ip->info = event_info;
	if (event_info->power) {
#ifdef CONFIG_HAS_EARLYSUSPEND
		ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
		ip->early_suspend.suspend = gpio_event_suspend;
		ip->early_suspend.resume = gpio_event_resume;
		register_early_suspend(&ip->early_suspend);
#endif
		ip->info->power(ip->info, 1);
	}

	err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT);
	if (err)
		goto err_call_all_func_failed;

	for (i = 0; i < dev_count; i++) {
		err = input_register_device(ip->input_devs->dev[i]);
		if (err) {
			KEY_LOGE("KEY_ERR: %s: Unable to register %s "
				"input device\n", __func__, ip->input_devs->dev[i]->name);
			goto err_input_register_device_failed;
		}
		registered++;
	}

	return 0;

err_input_register_device_failed:
	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
err_call_all_func_failed:
	if (event_info->power) {
#ifdef CONFIG_HAS_EARLYSUSPEND
		unregister_early_suspend(&ip->early_suspend);
#endif
		ip->info->power(ip->info, 0);
	}
	for (i = 0; i < registered; i++)
		input_unregister_device(ip->input_devs->dev[i]);
	for (i = dev_count - 1; i >= registered; i--) {
		input_free_device(ip->input_devs->dev[i]);
err_input_dev_alloc_failed:
		;
	}
	kfree(ip);
err_kp_alloc_failed:
	return err;
}
コード例 #20
0
ファイル: pwc-if.c プロジェクト: 0xroot/Blackphone-BP1-Kernel
static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct pwc_device *pdev = NULL;
	int vendor_id, product_id, type_id;
	int rc;
	int features = 0;
	int compression = 0;
	int my_power_save = power_save;
	char serial_number[30], *name;

	vendor_id = le16_to_cpu(udev->descriptor.idVendor);
	product_id = le16_to_cpu(udev->descriptor.idProduct);

	/* Check if we can handle this device */
	PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n",
		vendor_id, product_id,
		intf->altsetting->desc.bInterfaceNumber);

	/* the interfaces are probed one by one. We are only interested in the
	   video interface (0) now.
	   Interface 1 is the Audio Control, and interface 2 Audio itself.
	 */
	if (intf->altsetting->desc.bInterfaceNumber > 0)
		return -ENODEV;

	if (vendor_id == 0x0471) {
		switch (product_id) {
		case 0x0302:
			PWC_INFO("Philips PCA645VC USB webcam detected.\n");
			name = "Philips 645 webcam";
			type_id = 645;
			break;
		case 0x0303:
			PWC_INFO("Philips PCA646VC USB webcam detected.\n");
			name = "Philips 646 webcam";
			type_id = 646;
			break;
		case 0x0304:
			PWC_INFO("Askey VC010 type 2 USB webcam detected.\n");
			name = "Askey VC010 webcam";
			type_id = 646;
			break;
		case 0x0307:
			PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n");
			name = "Philips 675 webcam";
			type_id = 675;
			break;
		case 0x0308:
			PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
			name = "Philips 680 webcam";
			type_id = 680;
			break;
		case 0x030C:
			PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
			name = "Philips 690 webcam";
			type_id = 690;
			break;
		case 0x0310:
			PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
			name = "Philips 730 webcam";
			type_id = 730;
			break;
		case 0x0311:
			PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
			name = "Philips 740 webcam";
			type_id = 740;
			break;
		case 0x0312:
			PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
			name = "Philips 750 webcam";
			type_id = 750;
			break;
		case 0x0313:
			PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
			name = "Philips 720K/40 webcam";
			type_id = 720;
			break;
		case 0x0329:
			PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
			name = "Philips SPC 900NC webcam";
			type_id = 740;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x069A) {
		switch(product_id) {
		case 0x0001:
			PWC_INFO("Askey VC010 type 1 USB webcam detected.\n");
			name = "Askey VC010 webcam";
			type_id = 645;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x046d) {
		switch(product_id) {
		case 0x08b0:
			PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n");
			name = "Logitech QuickCam Pro 3000";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08b1:
			PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n");
			name = "Logitech QuickCam Notebook Pro";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08b2:
			PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n");
			name = "Logitech QuickCam Pro 4000";
			type_id = 740; /* CCD sensor */
			if (my_power_save == -1)
				my_power_save = 1;
			break;
		case 0x08b3:
			PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n");
			name = "Logitech QuickCam Zoom";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08B4:
			PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
			name = "Logitech QuickCam Zoom";
			type_id = 740; /* CCD sensor */
			if (my_power_save == -1)
				my_power_save = 1;
			break;
		case 0x08b5:
			PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
			name = "Logitech QuickCam Orbit";
			type_id = 740; /* CCD sensor */
			if (my_power_save == -1)
				my_power_save = 1;
			features |= FEATURE_MOTOR_PANTILT;
			break;
		case 0x08b6:
			PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n");
			name = "Cisco VT Camera";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08b7:
			PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n");
			name = "Logitech ViewPort AV 100";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08b8: /* Where this released? */
			PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
			name = "Logitech QuickCam (res.)";
			type_id = 730; /* Assuming CMOS */
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x055d) {
		/* I don't know the difference between the C10 and the C30;
		   I suppose the difference is the sensor, but both cameras
		   work equally well with a type_id of 675
		 */
		switch(product_id) {
		case 0x9000:
			PWC_INFO("Samsung MPC-C10 USB webcam detected.\n");
			name = "Samsung MPC-C10";
			type_id = 675;
			break;
		case 0x9001:
			PWC_INFO("Samsung MPC-C30 USB webcam detected.\n");
			name = "Samsung MPC-C30";
			type_id = 675;
			break;
		case 0x9002:
			PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n");
			name = "Samsung MPC-C30";
			type_id = 740;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x041e) {
		switch(product_id) {
		case 0x400c:
			PWC_INFO("Creative Labs Webcam 5 detected.\n");
			name = "Creative Labs Webcam 5";
			type_id = 730;
			if (my_power_save == -1)
				my_power_save = 1;
			break;
		case 0x4011:
			PWC_INFO("Creative Labs Webcam Pro Ex detected.\n");
			name = "Creative Labs Webcam Pro Ex";
			type_id = 740;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x04cc) {
		switch(product_id) {
		case 0x8116:
			PWC_INFO("Sotec Afina Eye USB webcam detected.\n");
			name = "Sotec Afina Eye";
			type_id = 730;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x06be) {
		switch(product_id) {
		case 0x8116:
			/* This is essentially the same cam as the Sotec Afina Eye */
			PWC_INFO("AME Co. Afina Eye USB webcam detected.\n");
			name = "AME Co. Afina Eye";
			type_id = 750;
			break;
		default:
			return -ENODEV;
			break;
		}

	}
	else if (vendor_id == 0x0d81) {
		switch(product_id) {
		case 0x1900:
			PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n");
			name = "Visionite VCS-UC300";
			type_id = 740; /* CCD sensor */
			break;
		case 0x1910:
			PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n");
			name = "Visionite VCS-UM100";
			type_id = 730; /* CMOS sensor */
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else
		return -ENODEV; /* Not any of the know types; but the list keeps growing. */

	if (my_power_save == -1)
		my_power_save = 0;

	memset(serial_number, 0, 30);
	usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
	PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number);

	if (udev->descriptor.bNumConfigurations > 1)
		PWC_WARNING("Warning: more than 1 configuration available.\n");

	/* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
	pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL);
	if (pdev == NULL) {
		PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
		return -ENOMEM;
	}
	pdev->type = type_id;
	pdev->features = features;
	pwc_construct(pdev); /* set min/max sizes correct */

	mutex_init(&pdev->capt_file_lock);
	mutex_init(&pdev->udevlock);
	spin_lock_init(&pdev->queued_bufs_lock);
	INIT_LIST_HEAD(&pdev->queued_bufs);

	pdev->udev = udev;
	pdev->power_save = my_power_save;

	/* Init videobuf2 queue structure */
	memset(&pdev->vb_queue, 0, sizeof(pdev->vb_queue));
	pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
	pdev->vb_queue.drv_priv = pdev;
	pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf);
	pdev->vb_queue.ops = &pwc_vb_queue_ops;
	pdev->vb_queue.mem_ops = &vb2_vmalloc_memops;
	vb2_queue_init(&pdev->vb_queue);

	/* Init video_device structure */
	memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
	strcpy(pdev->vdev.name, name);
	set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags);
	video_set_drvdata(&pdev->vdev, pdev);

	pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
	PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);

	/* Allocate USB command buffers */
	pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL);
	if (!pdev->ctrl_buf) {
		PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
		rc = -ENOMEM;
		goto err_free_mem;
	}

#ifdef CONFIG_USB_PWC_DEBUG
	/* Query sensor type */
	if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
		PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
				pdev->vdev.name,
				pwc_sensor_type_to_string(rc), rc);
	}
#endif

	/* Set the leds off */
	pwc_set_leds(pdev, 0, 0);

	/* Setup intial videomode */
	rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
				V4L2_PIX_FMT_YUV420, 30, &compression, 1);
	if (rc)
		goto err_free_mem;

	/* Register controls (and read default values from camera */
	rc = pwc_init_controls(pdev);
	if (rc) {
		PWC_ERROR("Failed to register v4l2 controls (%d).\n", rc);
		goto err_free_mem;
	}

	/* And powerdown the camera until streaming starts */
	pwc_camera_power(pdev, 0);

	/* Register the v4l2_device structure */
	pdev->v4l2_dev.release = pwc_video_release;
	rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev);
	if (rc) {
		PWC_ERROR("Failed to register v4l2-device (%d).\n", rc);
		goto err_free_controls;
	}

	pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
	pdev->vdev.v4l2_dev = &pdev->v4l2_dev;

	rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
	if (rc < 0) {
		PWC_ERROR("Failed to register as video device (%d).\n", rc);
		goto err_unregister_v4l2_dev;
	}
	PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev));

#ifdef CONFIG_USB_PWC_INPUT_EVDEV
	/* register webcam snapshot button input device */
	pdev->button_dev = input_allocate_device();
	if (!pdev->button_dev) {
		PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
		rc = -ENOMEM;
		goto err_video_unreg;
	}

	usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys));
	strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys));

	pdev->button_dev->name = "PWC snapshot button";
	pdev->button_dev->phys = pdev->button_phys;
	usb_to_input_id(pdev->udev, &pdev->button_dev->id);
	pdev->button_dev->dev.parent = &pdev->udev->dev;
	pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
	pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);

	rc = input_register_device(pdev->button_dev);
	if (rc) {
		input_free_device(pdev->button_dev);
		pdev->button_dev = NULL;
		goto err_video_unreg;
	}
#endif

	return 0;

err_video_unreg:
	video_unregister_device(&pdev->vdev);
err_unregister_v4l2_dev:
	v4l2_device_unregister(&pdev->v4l2_dev);
err_free_controls:
	v4l2_ctrl_handler_free(&pdev->ctrl_handler);
err_free_mem:
	kfree(pdev->ctrl_buf);
	kfree(pdev);
	return rc;
}
コード例 #21
0
static int wacom_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	static struct wacom_g5_platform_data *pdata; // = client->dev.platform_data;
	struct wacom_i2c *wac_i2c;
	struct input_dev *input;
	int ret = 0;



#ifdef CONFIG_OF
	printk(KERN_ERR "epen: %s, start,%d\n",__func__, __LINE__);

	pdata = kzalloc(sizeof(struct wacom_g5_platform_data), GFP_KERNEL);
	if (!pdata) {
		printk(KERN_ERR "epen: pdata err = ENOMEM!\n");
		return -ENOMEM;
	}

	pdata->x_invert = WACOM_X_INVERT;
	pdata->y_invert = WACOM_Y_INVERT;
	pdata->xy_switch = WACOM_XY_SWITCH;
	pdata->min_x = 0;
	pdata->max_x = WACOM_MAX_COORD_X;
	pdata->min_y = 0;
	pdata->max_y = WACOM_MAX_COORD_Y;
	pdata->min_pressure = 0;
	pdata->max_pressure = WACOM_MAX_PRESSURE;
	pdata->suspend_platform_hw = wacom_suspend_hw;
	pdata->resume_platform_hw = wacom_resume_hw;
	pdata->reset_platform_hw = wacom_reset_hw;
	pdata->register_cb = wacom_register_callbacks;
	pdata->compulsory_flash_mode = wacom_compulsory_flash_mode;

	pdata->get_irq_state = wacom_get_irq_state;

	ret = wacom_parse_dt(&client->dev, pdata);

	if (ret) {
		printk(KERN_ERR "Error parsing dt %d\n", ret);
		return ret;
	}

	wacom_init_gpio(pdata);

#else
	printk(KERN_ERR "epen: %s, start,%d\n",__func__, __LINE__);

	if (pdata == NULL) {
		printk(KERN_ERR "epen: %s: no pdata\n", __func__);
		ret = -ENODEV;
		goto err_i2c_fail;
	}
#endif

	/*Check I2C functionality */
	ret = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
	if (!ret) {
		printk(KERN_ERR "epen:No I2C functionality found\n");
		ret = -ENODEV;
		goto err_i2c_fail;
	}

	/*Obtain kernel memory space for wacom i2c */
	wac_i2c = kzalloc(sizeof(struct wacom_i2c), GFP_KERNEL);
	if (NULL == wac_i2c) {
		printk(KERN_ERR "epen:failed to allocate wac_i2c.\n");
		ret = -ENOMEM;
		goto err_alloc_mem;
	}

	wac_i2c->client_boot = i2c_new_dummy(client->adapter,
		WACOM_I2C_BOOT);
	if (!wac_i2c->client_boot) {
		dev_err(&client->dev, "Fail to register sub client[0x%x]\n",
			 WACOM_I2C_BOOT);
	}

	input = input_allocate_device();
	if (NULL == input) {
		printk(KERN_ERR "epen:failed to allocate input device.\n");
		ret = -ENOMEM;
		goto err_alloc_input_dev;
	}

	wacom_i2c_set_input_values(client, wac_i2c, input);

	wac_i2c->wac_feature = &wacom_feature_EMR;
	wac_i2c->wac_pdata = pdata;
	wac_i2c->input_dev = input;
	wac_i2c->client = client;

	//wac_i2c->irq = client->irq;
	wac_i2c->irq = gpio_to_irq(pdata->gpio_irq); 	//dtsi

	//printk(KERN_ERR "epen: irq %d, %d, %d\n", wac_i2c->irq, pdata->gpio_irq, client->irq);
	irq_set_irq_type(wac_i2c->irq, IRQ_TYPE_EDGE_RISING);	// dtsi

	/* init_completion(&wac_i2c->init_done); */
#ifdef WACOM_PDCT_WORK_AROUND
	wac_i2c->irq_pdct = gpio_to_irq(pdata->gpio_pendct);
	wac_i2c->pen_pdct = PDCT_NOSIGNAL;

	irq_set_irq_type(wac_i2c->irq_pdct , IRQ_TYPE_EDGE_BOTH);	// dtsi
#endif
#ifdef WACOM_PEN_DETECT
	wac_i2c->gpio_pen_insert = pdata->gpio_pen_insert;
#endif
#ifdef WACOM_IMPORT_FW_ALGO
	wac_i2c->use_offset_table = true;
	wac_i2c->use_aveTransition = false;
	wacom_init_fw_algo(wac_i2c);
#endif

	/*Change below if irq is needed */
	wac_i2c->irq_flag = 1;

	/*Register callbacks */
	wac_i2c->callbacks.check_prox = wacom_check_emr_prox;
	if (wac_i2c->wac_pdata->register_cb)
		wac_i2c->wac_pdata->register_cb(&wac_i2c->callbacks);

	/* Firmware Feature */
	wacom_i2c_init_firm_data();

	/* Power on */
	wac_i2c->wac_pdata->resume_platform_hw();
	msleep(60); // for booting time,  msleep(200);
	wac_i2c->power_enable = true;
	wac_i2c->pwr_flag = true;

	printk(KERN_ERR "epen: %s, query, %d\n", __func__, __LINE__);
	wacom_i2c_query(wac_i2c);

	wacom_init_abs_params(wac_i2c);
	input_set_drvdata(input, wac_i2c);

	/*Change below if irq is needed */
	wac_i2c->irq_flag = 1;

	/*Set client data */
	i2c_set_clientdata(client, wac_i2c);
	i2c_set_clientdata(wac_i2c->client_boot, wac_i2c);

	/*Initializing for semaphor */
	mutex_init(&wac_i2c->lock);
	mutex_init(&wac_i2c->update_lock);
	mutex_init(&wac_i2c->irq_lock);
	wake_lock_init(&wac_i2c->fw_wakelock, WAKE_LOCK_SUSPEND, "wacom");
	INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work);
#ifdef LCD_FREQ_SYNC
	mutex_init(&wac_i2c->freq_write_lock);
	INIT_WORK(&wac_i2c->lcd_freq_work, wacom_i2c_lcd_freq_work);
	INIT_DELAYED_WORK(&wac_i2c->lcd_freq_done_work, wacom_i2c_finish_lcd_freq_work);
	if (likely(system_rev >= LCD_FREQ_SUPPORT_HWID))
		wac_i2c->use_lcd_freq_sync = true;
#endif
#ifdef WACOM_USE_SOFTKEY_BLOCK
	INIT_DELAYED_WORK(&wac_i2c->softkey_block_work, wacom_i2c_block_softkey_work);
	wac_i2c->block_softkey = false;
#endif
	INIT_WORK(&wac_i2c->update_work, wacom_i2c_update_work);
	/*init wacom booster*/
#if defined(WACOM_BOOSTER_DVFS)
	wacom_init_dvfs(wac_i2c);
#elif defined(WACOM_BOOSTER)
	wacom_init_dvfs(wac_i2c);
	wac_i2c->boost_level = WACOM_BOOSTER_LEVEL2;
#endif
	printk(KERN_ERR "epen: %s,%d \n", __func__, __LINE__);

	/*Before registering input device, data in each input_dev must be set */
	ret = input_register_device(input);
	if (ret) {
		pr_err("epen:failed to register input device.\n");
		goto err_register_device;
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
	wac_i2c->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	wac_i2c->early_suspend.suspend = wacom_i2c_early_suspend;
	wac_i2c->early_suspend.resume = wacom_i2c_late_resume;
	register_early_suspend(&wac_i2c->early_suspend);
#endif

	wac_i2c->dev = device_create(sec_class, NULL, 0, NULL, "sec_epen");
	if (IS_ERR(wac_i2c->dev)) {
		printk(KERN_ERR "Failed to create device(wac_i2c->dev)!\n");
		ret = -ENODEV;
		goto err_create_device;
	}

	dev_set_drvdata(wac_i2c->dev, wac_i2c);

	ret = sysfs_create_group(&wac_i2c->dev->kobj, &epen_attr_group);
	if (ret) {
		printk(KERN_ERR
			    "epen:failed to create sysfs group\n");
		goto err_sysfs_create_group;
	}

	/* firmware info */
	printk(KERN_NOTICE "epen:wacom fw ver : 0x%x, new fw ver : 0x%x\n",
	       wac_i2c->wac_feature->fw_version, fw_ver_file);

	/*Request IRQ */
	if (wac_i2c->irq_flag) {
		ret =
		    request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt,
					 IRQF_DISABLED | EPEN_IRQF_TRIGGER_TYPE |
					 IRQF_ONESHOT, "sec_epen_irq", wac_i2c);
		if (ret < 0) {
			printk(KERN_ERR
			       "epen:failed to request irq(%d) - %d\n",
			       wac_i2c->irq, ret);
			goto err_request_irq;
		}
		printk(KERN_ERR "epen: %s,%d \n", __func__, __LINE__);

#if defined(WACOM_PDCT_WORK_AROUND)
		ret =
			request_threaded_irq(wac_i2c->irq_pdct, NULL,
					wacom_interrupt_pdct,
					IRQF_DISABLED | IRQF_TRIGGER_RISING |
					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
					"sec_epen_pdct", wac_i2c);
		if (ret < 0) {
			printk(KERN_ERR
				"epen:failed to request irq(%d) - %d\n",
				wac_i2c->irq_pdct, ret);
			goto err_request_irq;
		}
#endif
	}
#ifdef WACOM_PEN_DETECT
	init_pen_insert(wac_i2c);
#endif
	printk(KERN_ERR "epen: %s,%d \n", __func__, __LINE__);

	wac_i2c->update_info.forced = false;
	wac_i2c->update_info.fw_path = FW_BUILT_IN;
	schedule_work(&wac_i2c->update_work);
	/*complete_all(&wac_i2c->init_done);*/


	printk(KERN_ERR "epen: %s, -end %d\n", __func__, __LINE__);

	return 0;

 err_request_irq:
	wake_lock_destroy(&wac_i2c->fw_wakelock);
	sysfs_remove_group(&wac_i2c->dev->kobj,
		&epen_attr_group);
 err_sysfs_create_group:
	device_destroy(sec_class, (dev_t)NULL);
 err_create_device:
	input_unregister_device(input);
	input = NULL;
 err_register_device:
#ifdef LCD_FREQ_SYNC
	mutex_destroy(&wac_i2c->freq_write_lock);
#endif
	mutex_destroy(&wac_i2c->irq_lock);
	mutex_destroy(&wac_i2c->update_lock);
	mutex_destroy(&wac_i2c->lock);
	input_free_device(input);
 err_alloc_input_dev:
	kfree(wac_i2c);
	wac_i2c = NULL;
 err_alloc_mem:
 err_i2c_fail:
	return ret;
}
コード例 #22
0
static int wacom_i2c_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	struct wacom_i2c *wac_i2c;
	struct wacom_g5_platform_data *pdata = client->dev.platform_data;
	int i, ret;
	i = ret = 0;

	printk(KERN_DEBUG "[E-PEN]:%s:\n", __func__);

	/*Check I2C functionality*/
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		goto err3;

	/*Obtain kernel memory space for wacom i2c*/
	wac_i2c = kzalloc(sizeof(struct wacom_i2c), GFP_KERNEL);
	wac_i2c->wac_feature = &wacom_feature_EMR;

	/*Initializing for semaphor*/
	mutex_init(&wac_i2c->lock);

	/*Register platform data*/
	wac_i2c->wac_pdata = client->dev.platform_data;

	/*Register callbacks*/
	wac_i2c->callbacks.check_prox = wacom_check_emr_prox;
	if (wac_i2c->wac_pdata->register_cb)
		wac_i2c->wac_pdata->register_cb(&wac_i2c->callbacks);

	/*Register wacom i2c to input device*/
	wac_i2c->input_dev = input_allocate_device();
	if (wac_i2c == NULL || wac_i2c->input_dev == NULL)
		goto fail;
	wacom_i2c_set_input_values(client, wac_i2c, wac_i2c->input_dev);

	wac_i2c->client = client;
	wac_i2c->irq = client->irq;

	/*Change below if irq is needed*/
	wac_i2c->irq_flag = 1;

#ifdef CONFIG_HAS_EARLYSUSPEND
		wac_i2c->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
		wac_i2c->early_suspend.suspend = wacom_i2c_early_suspend;
		wac_i2c->early_suspend.resume = wacom_i2c_late_resume;
		register_early_suspend(&wac_i2c->early_suspend);
#endif

	/*Init Featreus by hw rev*/
	if( system_rev >= 6 ) {	/* rev 03 */
		printk("[E-PEN] Wacom driver is working for 4.4mm pitch pad.\n");

		/* Firmware Feature */
		Firmware_version_of_file = Firmware_version_of_file_44;
		Binary = Binary_44;
	}
	else {
		printk("[E-PEN] Wacom driver is working for 4.8mm pitch pad.\n");

		/* Firmware Feature */
		Firmware_version_of_file = Firmware_version_of_file_48;
		Binary = Binary_48;
	}
	init_offset_tables();
	INIT_WORK(&wac_i2c->update_work, update_work_func);
	INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work);

	/* Reset IC */
	gpio_direction_output(GPIO_PEN_RESET, 0);
	msleep(200);
	gpio_direction_output(GPIO_PEN_RESET, 1);
	msleep(200);
	ret = wacom_i2c_query(wac_i2c);

	if( ret < 0 )
		epen_reset_result = false;
	else
		epen_reset_result = true;

	input_set_abs_params(wac_i2c->input_dev, ABS_X, pdata->min_x,
		pdata->max_x, 4, 0);
	input_set_abs_params(wac_i2c->input_dev, ABS_Y, pdata->min_y,
		pdata->max_y, 4, 0);
	input_set_abs_params(wac_i2c->input_dev, ABS_PRESSURE, pdata->min_pressure,
		pdata->max_pressure, 0, 0);
	input_set_drvdata(wac_i2c->input_dev, wac_i2c);

	/*Set client data*/
	i2c_set_clientdata(client, wac_i2c);

	/*Before registering input device, data in each input_dev must be set*/
	if (input_register_device(wac_i2c->input_dev))
		goto err2;

	g_client = client;

	/*  if(wac_i2c->irq_flag) */
	/*   disable_irq(wac_i2c->irq); */

	sec_epen= device_create(sec_class, NULL, 0, NULL, "sec_epen");
	dev_set_drvdata(sec_epen, wac_i2c);

	if (IS_ERR(sec_epen))
			printk(KERN_ERR "Failed to create device(sec_epen)!\n");

	if (device_create_file(sec_epen, &dev_attr_epen_firm_update)< 0)
			printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_firm_update.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_firm_update_status)< 0)
			printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_firm_update_status.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_firm_version)< 0)
			printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_firm_version.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_rotation)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_rotation.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_hand)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_hand.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_reset)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_reset.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_reset_result)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_reset_result.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_checksum)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_checksum.attr.name);

	if (device_create_file(sec_epen, &dev_attr_epen_checksum_result)< 0)
		printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_checksum_result.attr.name);
	
	/*Request IRQ*/
	if (wac_i2c->irq_flag) {
		ret = request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt, IRQF_DISABLED|IRQF_TRIGGER_RISING|IRQF_ONESHOT, wac_i2c->name, wac_i2c);
		if (ret < 0)
			goto err1;
	}

	/* firmware update */
	printk(KERN_NOTICE "[E-PEN] wacom fw ver : 0x%x, new fw ver : 0x%x\n",
		wac_i2c->wac_feature->fw_version, Firmware_version_of_file);
	if( wac_i2c->wac_feature->fw_version < Firmware_version_of_file ) {
		schedule_work(&wac_i2c->update_work);
	}

	return 0;

err3:
	printk(KERN_ERR "[E-PEN]: No I2C functionality found\n");
	return -ENODEV;

err2:
	printk(KERN_ERR "[E-PEN]: err2 occured\n");
	input_free_device(wac_i2c->input_dev);
	return -EIO;

err1:
	printk(KERN_ERR "[E-PEN]: err1 occured(num:%d)\n", ret);
	input_free_device(wac_i2c->input_dev);
	wac_i2c->input_dev = NULL;
	return -EIO;

fail:
	printk(KERN_ERR "[E-PEN]: fail occured\n");
	return -ENOMEM;
}
コード例 #23
0
ファイル: lkkbd.c プロジェクト: 3sOx/asuswrt-merlin
/*
 * lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
 */
static int
lkkbd_connect (struct serio *serio, struct serio_driver *drv)
{
	struct lkkbd *lk;
	struct input_dev *input_dev;
	int i;
	int err;

	lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL);
	input_dev = input_allocate_device ();
	if (!lk || !input_dev) {
		err = -ENOMEM;
		goto fail1;
	}

	lk->serio = serio;
	lk->dev = input_dev;
	INIT_WORK (&lk->tq, lkkbd_reinit);
	lk->bell_volume = bell_volume;
	lk->keyclick_volume = keyclick_volume;
	lk->ctrlclick_volume = ctrlclick_volume;
	memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);

	strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name));
	snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);

	input_dev->name = lk->name;
	input_dev->phys = lk->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->id.vendor = SERIO_LKKBD;
	input_dev->id.product = 0;
	input_dev->id.version = 0x0100;
	input_dev->dev.parent = &serio->dev;
	input_dev->event = lkkbd_event;

	input_set_drvdata (input_dev, lk);

	set_bit (EV_KEY, input_dev->evbit);
	set_bit (EV_LED, input_dev->evbit);
	set_bit (EV_SND, input_dev->evbit);
	set_bit (EV_REP, input_dev->evbit);
	set_bit (LED_CAPSL, input_dev->ledbit);
	set_bit (LED_SLEEP, input_dev->ledbit);
	set_bit (LED_COMPOSE, input_dev->ledbit);
	set_bit (LED_SCROLLL, input_dev->ledbit);
	set_bit (SND_BELL, input_dev->sndbit);
	set_bit (SND_CLICK, input_dev->sndbit);

	input_dev->keycode = lk->keycode;
	input_dev->keycodesize = sizeof (lk_keycode_t);
	input_dev->keycodemax = LK_NUM_KEYCODES;
	for (i = 0; i < LK_NUM_KEYCODES; i++)
		set_bit (lk->keycode[i], input_dev->keybit);

	serio_set_drvdata (serio, lk);

	err = serio_open (serio, drv);
	if (err)
		goto fail2;

	err = input_register_device (lk->dev);
	if (err)
		goto fail3;

	lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);

	return 0;

 fail3:	serio_close (serio);
 fail2:	serio_set_drvdata (serio, NULL);
 fail1:	input_free_device (input_dev);
	kfree (lk);
	return err;
}
コード例 #24
0
static int spear_kbd_probe(struct platform_device *pdev)
{
	struct kbd_platform_data *pdata = dev_get_platdata(&pdev->dev);
	const struct matrix_keymap_data *keymap = pdata ? pdata->keymap : NULL;
	struct spear_kbd *kbd;
	struct input_dev *input_dev;
	struct resource *res;
	int irq;
	int error;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "not able to get irq for the device\n");
		return irq;
	}

	kbd = devm_kzalloc(&pdev->dev, sizeof(*kbd), GFP_KERNEL);
	if (!kbd) {
		dev_err(&pdev->dev, "not enough memory for driver data\n");
		return -ENOMEM;
	}

	input_dev = devm_input_allocate_device(&pdev->dev);
	if (!input_dev) {
		dev_err(&pdev->dev, "unable to allocate input device\n");
		return -ENOMEM;
	}

	kbd->input = input_dev;
	kbd->irq = irq;

	if (!pdata) {
		error = spear_kbd_parse_dt(pdev, kbd);
		if (error)
			return error;
	} else {
		kbd->mode = pdata->mode;
		kbd->rep = pdata->rep;
		kbd->suspended_rate = pdata->suspended_rate;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	kbd->io_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(kbd->io_base))
		return PTR_ERR(kbd->io_base);

	kbd->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(kbd->clk))
		return PTR_ERR(kbd->clk);

	input_dev->name = "Spear Keyboard";
	input_dev->phys = "keyboard/input0";
	input_dev->id.bustype = BUS_HOST;
	input_dev->id.vendor = 0x0001;
	input_dev->id.product = 0x0001;
	input_dev->id.version = 0x0100;
	input_dev->open = spear_kbd_open;
	input_dev->close = spear_kbd_close;

	error = matrix_keypad_build_keymap(keymap, NULL, NUM_ROWS, NUM_COLS,
					   kbd->keycodes, input_dev);
	if (error) {
		dev_err(&pdev->dev, "Failed to build keymap\n");
		return error;
	}

	if (kbd->rep)
		__set_bit(EV_REP, input_dev->evbit);
	input_set_capability(input_dev, EV_MSC, MSC_SCAN);

	input_set_drvdata(input_dev, kbd);

	error = devm_request_irq(&pdev->dev, irq, spear_kbd_interrupt, 0,
			"keyboard", kbd);
	if (error) {
		dev_err(&pdev->dev, "request_irq failed\n");
		return error;
	}

	error = clk_prepare(kbd->clk);
	if (error)
		return error;

	error = input_register_device(input_dev);
	if (error) {
		dev_err(&pdev->dev, "Unable to register keyboard device\n");
		clk_unprepare(kbd->clk);
		return error;
	}

	device_init_wakeup(&pdev->dev, 1);
	platform_set_drvdata(pdev, kbd);

	return 0;
}
コード例 #25
0
static int __init s3c2410ts_probe(struct platform_device *pdev)
{
	int rc;
	struct s3c2410_ts_mach_info *info;
	struct input_dev *input_dev;
	int ret = 0;

	dev_info(&pdev->dev, "Starting\n");

	info = (struct s3c2410_ts_mach_info *)pdev->dev.platform_data;

	if (!info)
	{
		dev_err(&pdev->dev, "Hm... too bad: no platform data for ts\n");
		return -EINVAL;
	}

#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
	printk(DEBUG_LVL "Entering s3c2410ts_init\n");
#endif

	adc_clock = clk_get(NULL, "adc");
	if (!adc_clock) {
		dev_err(&pdev->dev, "failed to get adc clock source\n");
		return -ENOENT;
	}
	clk_enable(adc_clock);

#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUG
	printk(DEBUG_LVL "got and enabled clock\n");
#endif

	base_addr = ioremap(S3C2410_PA_ADC,0x20);
	if (base_addr == NULL) {
		dev_err(&pdev->dev, "Failed to remap register block\n");
		ret = -ENOMEM;
		goto bail0;
	}


	/* If we acutally are a S3C2410: Configure GPIOs */
	if (!strcmp(pdev->name, "s3c2410-ts"))
		s3c2410_ts_connect();

	if ((info->presc & 0xff) > 0)
		writel(S3C2410_ADCCON_PRSCEN |
		       S3C2410_ADCCON_PRSCVL(info->presc&0xFF),
						    base_addr + S3C2410_ADCCON);
	else
		writel(0, base_addr+S3C2410_ADCCON);

	/* Initialise registers */
	if ((info->delay & 0xffff) > 0)
		writel(info->delay & 0xffff,  base_addr + S3C2410_ADCDLY);

	writel(WAIT4INT(0), base_addr + S3C2410_ADCTSC);

	/* Initialise input stuff */
	memset(&ts, 0, sizeof(struct s3c2410ts));
	input_dev = input_allocate_device();

	if (!input_dev) {
		dev_err(&pdev->dev, "Unable to allocate the input device\n");
		ret = -ENOMEM;
		goto bail1;
	}

	ts.dev = input_dev;
	ts.dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) |
			   BIT_MASK(EV_ABS);
	ts.dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
	input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0);
	input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0);
	input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0);

	ts.dev->name = s3c2410ts_name;
	ts.dev->id.bustype = BUS_RS232;
	ts.dev->id.vendor = 0xDEAD;
	ts.dev->id.product = 0xBEEF;
	ts.dev->id.version = S3C2410TSVERSION;
	ts.state = TS_STATE_STANDBY;
	ts.event_fifo = kfifo_alloc(TS_EVENT_FIFO_SIZE, GFP_KERNEL, NULL);
	if (IS_ERR(ts.event_fifo)) {
		ret = -EIO;
		goto bail2;
	}

	/* create the filter chain set up for the 2 coordinates we produce */
	ts.chain = ts_filter_chain_create(pdev, info->filter_config, 2);

	if (IS_ERR(ts.chain))
		goto bail2;

	ts_filter_chain_clear(ts.chain);

	/* Get irqs */
	if (request_irq(IRQ_ADC, stylus_action, IRQF_SAMPLE_RANDOM,
						    "s3c2410_action", ts.dev)) {
		dev_err(&pdev->dev, "Could not allocate ts IRQ_ADC !\n");
		iounmap(base_addr);
		ret = -EIO;
		goto bail3;
	}
	if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM,
			"s3c2410_action", ts.dev)) {
		dev_err(&pdev->dev, "Could not allocate ts IRQ_TC !\n");
		free_irq(IRQ_ADC, ts.dev);
		iounmap(base_addr);
		ret = -EIO;
		goto bail4;
	}

	dev_info(&pdev->dev, "Successfully loaded\n");

	/* All went ok, so register to the input system */
	rc = input_register_device(ts.dev);
	if (rc) {
		ret = -EIO;
		goto bail5;
	}

	return 0;

bail5:
	free_irq(IRQ_TC, ts.dev);
	free_irq(IRQ_ADC, ts.dev);
	clk_disable(adc_clock);
	iounmap(base_addr);
	disable_irq(IRQ_TC);
bail4:
	disable_irq(IRQ_ADC);
bail3:
	ts_filter_chain_destroy(ts.chain);
	kfifo_free(ts.event_fifo);
bail2:
	input_unregister_device(ts.dev);
bail1:
	iounmap(base_addr);
bail0:

	return ret;
}
コード例 #26
0
static int __devinit tca6416_keypad_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	struct tca6416_keys_platform_data *pdata;
	struct tca6416_keypad_chip *chip;
	struct input_dev *input;
	int error;
	int i;

	/* Check functionality */
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
		dev_err(&client->dev, "%s adapter not supported\n",
			dev_driver_string(&client->adapter->dev));
		return -ENODEV;
	}

	pdata = client->dev.platform_data;
	if (!pdata) {
		dev_dbg(&client->dev, "no platform data\n");
		return -EINVAL;
	}

	chip = kzalloc(sizeof(struct tca6416_keypad_chip) +
		       pdata->nbuttons * sizeof(struct tca6416_button),
		       GFP_KERNEL);
	input = input_allocate_device();
	if (!chip || !input) {
		error = -ENOMEM;
		goto fail1;
	}

	chip->client = client;
	chip->input = input;
	chip->pinmask = pdata->pinmask;
	chip->use_polling = pdata->use_polling;

	INIT_DELAYED_WORK(&chip->dwork, tca6416_keys_work_func);

	input->phys = "tca6416-keys/input0";
	input->name = client->name;
	input->dev.parent = &client->dev;

	input->open = tca6416_keys_open;
	input->close = tca6416_keys_close;

	input->id.bustype = BUS_HOST;
	input->id.vendor = 0x0001;
	input->id.product = 0x0001;
	input->id.version = 0x0100;

	/* Enable auto repeat feature of Linux input subsystem */
	if (pdata->rep)
		__set_bit(EV_REP, input->evbit);

	for (i = 0; i < pdata->nbuttons; i++) {
		unsigned int type;

		chip->buttons[i] = pdata->buttons[i];
		type = (pdata->buttons[i].type) ?: EV_KEY;
		input_set_capability(input, type, pdata->buttons[i].code);
	}

	input_set_drvdata(input, chip);

	/*
	 * Initialize cached registers from their original values.
	 * we can't share this chip with another i2c master.
	 */
	error = tca6416_setup_registers(chip);
	if (error)
		goto fail1;

	if (!chip->use_polling) {
		if (pdata->irq_is_gpio)
			chip->irqnum = gpio_to_irq(client->irq);
		else
			chip->irqnum = client->irq;

		error = request_threaded_irq(chip->irqnum, NULL,
					     tca6416_keys_isr,
					     IRQF_TRIGGER_FALLING,
					     "tca6416-keypad", chip);
		if (error) {
			dev_dbg(&client->dev,
				"Unable to claim irq %d; error %d\n",
				chip->irqnum, error);
			goto fail1;
		}
		disable_irq(chip->irqnum);
	}

	error = input_register_device(input);
	if (error) {
		dev_dbg(&client->dev,
			"Unable to register input device, error: %d\n", error);
		goto fail2;
	}

	i2c_set_clientdata(client, chip);

	return 0;

fail2:
	if (!chip->use_polling) {
		free_irq(chip->irqnum, chip);
		enable_irq(chip->irqnum);
	}
fail1:
	input_free_device(input);
	kfree(chip);
	return error;
}
コード例 #27
0
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_xpad *xpad;
	struct input_dev *input_dev;
	struct usb_endpoint_descriptor *ep_irq_in;
	int i, error;

	for (i = 0; xpad_device[i].idVendor; i++) {
		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
			break;
	}

	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!xpad || !input_dev) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->idata = usb_alloc_coherent(udev, XPAD_PKT_LEN,
					 GFP_KERNEL, &xpad->idata_dma);
	if (!xpad->idata) {
		error = -ENOMEM;
		goto fail1;
	}

	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
	if (!xpad->irq_in) {
		error = -ENOMEM;
		goto fail2;
	}

	xpad->udev = udev;
	xpad->mapping = xpad_device[i].mapping;
	xpad->xtype = xpad_device[i].xtype;

	if (xpad->xtype == XTYPE_UNKNOWN) {
		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
				xpad->xtype = XTYPE_XBOX360W;
			else
				xpad->xtype = XTYPE_XBOX360;
		} else
			xpad->xtype = XTYPE_XBOX;

		if (dpad_to_buttons)
			xpad->mapping |= MAP_DPAD_TO_BUTTONS;
		if (triggers_to_buttons)
			xpad->mapping |= MAP_TRIGGERS_TO_BUTTONS;
		if (sticks_to_null)
			xpad->mapping |= MAP_STICKS_TO_NULL;
	}

	xpad->dev = input_dev;
	usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
	strlcat(xpad->phys, "/input0", sizeof(xpad->phys));

	input_dev->name = xpad_device[i].name;
	input_dev->phys = xpad->phys;
	usb_to_input_id(udev, &input_dev->id);
	input_dev->dev.parent = &intf->dev;

	input_set_drvdata(input_dev, xpad);

	input_dev->open = xpad_open;
	input_dev->close = xpad_close;

	input_dev->evbit[0] = BIT_MASK(EV_KEY);

	if (!(xpad->mapping & MAP_STICKS_TO_NULL)) {
		input_dev->evbit[0] |= BIT_MASK(EV_ABS);
		/* set up axes */
		for (i = 0; xpad_abs[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs[i]);
	}

	/* set up standard buttons */
	for (i = 0; xpad_common_btn[i] >= 0; i++)
		__set_bit(xpad_common_btn[i], input_dev->keybit);

	/* set up model-specific ones */
	if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) {
		for (i = 0; xpad360_btn[i] >= 0; i++)
			__set_bit(xpad360_btn[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_btn[i] >= 0; i++)
			__set_bit(xpad_btn[i], input_dev->keybit);
	}

	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
		for (i = 0; xpad_btn_pad[i] >= 0; i++)
			__set_bit(xpad_btn_pad[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_pad[i] >= 0; i++)
		    xpad_set_up_abs(input_dev, xpad_abs_pad[i]);
	}

	if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) {
		for (i = 0; xpad_btn_triggers[i] >= 0; i++)
			__set_bit(xpad_btn_triggers[i], input_dev->keybit);
	} else {
		for (i = 0; xpad_abs_triggers[i] >= 0; i++)
			xpad_set_up_abs(input_dev, xpad_abs_triggers[i]);
	}

	error = xpad_init_output(intf, xpad);
	if (error)
		goto fail3;

	error = xpad_init_ff(xpad);
	if (error)
		goto fail4;

	error = xpad_led_probe(xpad);
	if (error)
		goto fail5;

	ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
	usb_fill_int_urb(xpad->irq_in, udev,
			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
			 xpad, ep_irq_in->bInterval);
	xpad->irq_in->transfer_dma = xpad->idata_dma;
	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	error = input_register_device(xpad->dev);
	if (error)
		goto fail6;

	usb_set_intfdata(intf, xpad);

	if (xpad->xtype == XTYPE_XBOX360W) {
		/*
		 * Setup the message to set the LEDs on the
		 * controller when it shows up
		 */
		xpad->bulk_out = usb_alloc_urb(0, GFP_KERNEL);
		if (!xpad->bulk_out) {
			error = -ENOMEM;
			goto fail7;
		}

		xpad->bdata = kzalloc(XPAD_PKT_LEN, GFP_KERNEL);
		if (!xpad->bdata) {
			error = -ENOMEM;
			goto fail8;
		}

		xpad->bdata[2] = 0x08;
		switch (intf->cur_altsetting->desc.bInterfaceNumber) {
		case 0:
			xpad->bdata[3] = 0x42;
			break;
		case 2:
			xpad->bdata[3] = 0x43;
			break;
		case 4:
			xpad->bdata[3] = 0x44;
			break;
		case 6:
			xpad->bdata[3] = 0x45;
		}

		ep_irq_in = &intf->cur_altsetting->endpoint[1].desc;
		usb_fill_bulk_urb(xpad->bulk_out, udev,
				usb_sndbulkpipe(udev, ep_irq_in->bEndpointAddress),
				xpad->bdata, XPAD_PKT_LEN, xpad_bulk_out, xpad);

		/*
		 * Submit the int URB immediately rather than waiting for open
		 * because we get status messages from the device whether
		 * or not any controllers are attached.  In fact, it's
		 * exactly the message that a controller has arrived that
		 * we're waiting for.
		 */
		xpad->irq_in->dev = xpad->udev;
		error = usb_submit_urb(xpad->irq_in, GFP_KERNEL);
		if (error)
			goto fail9;
	}

	return 0;

 fail9:	kfree(xpad->bdata);
 fail8:	usb_free_urb(xpad->bulk_out);
 fail7:	input_unregister_device(input_dev);
	input_dev = NULL;
 fail6:	xpad_led_disconnect(xpad);
 fail5:	if (input_dev)
		input_ff_destroy(input_dev);
 fail4:	xpad_deinit_output(xpad);
 fail3:	usb_free_urb(xpad->irq_in);
 fail2:	usb_free_coherent(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
 fail1:	input_free_device(input_dev);
	kfree(xpad);
	return error;

}
コード例 #28
0
ファイル: bh1721.c プロジェクト: ferow2k/NeatKernel_captivate
static int bh1721_i2c_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct input_dev *input_dev;
	struct bh1721_data *bh1721;
	struct bh1721_platform_data *pdata = client->dev.platform_data;

	if (!pdata) {
		pr_err("%s: missing 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;
	}

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


	bh1721->pdata = pdata;
	bh1721->reset = pdata->reset;
	bh1721->i2c_client = client;
	i2c_set_clientdata(client, bh1721);

	if (bh1721->reset)
		bh1721->reset();

	mutex_init(&bh1721->power_lock);

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

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	bh1721->wq = create_singlethread_workqueue("bh1721_wq");
	if (!bh1721->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(&bh1721->work_light, bh1721_work_func_light);

	/* 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, bh1721);
	input_dev->name = "lightsensor-level";
	input_set_capability(input_dev, EV_ABS, ABS_MISC);
	input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);

	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;
	}
	bh1721->light_input_dev = input_dev;

	ret = sysfs_create_group(&input_dev->dev.kobj,&light_attribute_group);
	if (ret) {
		printk("Creating bh1721 attribute group failed");
		goto error_device;
	}

	/* set sysfs for light sensor test mode*/
	lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(lightsensor_class))
	{
		printk("Failed to create class(lightsensor)!\n");
		goto error_device;
	}
	switch_cmd_dev = device_create(lightsensor_class, NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(switch_cmd_dev))
	{
		printk("Failed to create device(switch_cmd_dev)!\n");
		goto DESTROY_CLASS;
	}
	if (device_create_file(switch_cmd_dev, &dev_attr_lightsensor_file_state) < 0)
	{
		printk("Failed to create device file(%s)!\n", dev_attr_lightsensor_file_state.attr.name);
		device_remove_file(switch_cmd_dev, &dev_attr_lightsensor_file_state);
		goto DESTROY_DEVICE;
	}
	if (device_create_file(switch_cmd_dev, &dev_attr_lightsensor_file_illuminance) < 0)
	{
		printk("Failed to create device file(%s)!\n", dev_attr_lightsensor_file_illuminance.attr.name);
		device_remove_file(switch_cmd_dev, &dev_attr_lightsensor_file_illuminance);
		goto DESTROY_DEVICE;
	}
	if (device_create_file(switch_cmd_dev, &dev_attr_lightsensor_file_cmd) < 0)
	{
		printk("Failed to create device file(%s)!\n", dev_attr_lightsensor_file_cmd.attr.name);
		goto DESTROY_DEVICE;
	}
	dev_set_drvdata(switch_cmd_dev, bh1721);

	printk("[%s]: Light Sensor probe complete.", __func__);

	goto done;

	/* error, unwind it all */
DESTROY_DEVICE:
	device_destroy(lightsensor_class,0);
DESTROY_CLASS:
	class_destroy(lightsensor_class);
error_device:
	sysfs_remove_group(&client->dev.kobj, &light_attribute_group);
err_input_register_device_light:
	input_unregister_device(bh1721->light_input_dev);
err_input_allocate_device_light:
	destroy_workqueue(bh1721->wq);
err_create_workqueue:
	mutex_destroy(&bh1721->power_lock);
	kfree(bh1721);
done:
	return ret;
}
コード例 #29
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("[TMP] %s, %d\n", __func__, __LINE__);

	nondetect = PROX_NONDETECT;
	detect = PROX_DETECT;
/*#else
	if (board_hw_revision >= 0x07) {
		nondetect = PROX_REV_07_NONDETECT;
		detect = PROX_REV_07_DETECT;
	} else {
		nondetect = PROX_REV_06_NONDETECT;
		detect = PROX_REV_06_DETECT;
	}
#endif*/
	pr_info("%s: %02x %02x\n", __func__, nondetect, detect);
	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return ret;
	}

	if (!pdata->power) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return ret;
	}

	/* power on gp2a */
	pdata->power(true);

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

	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_lock);

	/* 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;
	}
	input_dev->name = "proximity_sensor";
	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_allocate_device_proximity;
	}

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

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

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	INIT_WORK(&gp2a->work_prox, gp2a_prox_work_func);
	ret = gp2a_setup_irq(gp2a);

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

	ret = sensors_register(gp2a->proximity_dev, gp2a,
		proxi_attrs, "proximity_sensor");
	if (ret < 0) {
		pr_info("%s: could not sensors_register\n", __func__);
		goto exit_gp2a_sensors_register;
	}

#ifdef CONFIG_SENSOR_USE_SYMLINK
	ret =  sensors_initialize_symlink(gp2a->proximity_input_dev);
	if (ret) {
		pr_err("%s: cound not make proximity sensor symlink(%d).\n",
			__func__, ret);
		goto exit_sensors_initialize_symlink;
	}
#endif

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

	pr_info("[TMP] %s, %d\n", __func__, __LINE__);

	pdata->power(false);
	goto done;

	/* error, unwind it all */
#ifdef CONFIG_SENSOR_USE_SYMLINK
exit_sensors_initialize_symlink:
#endif
exit_gp2a_sensors_register:
	free_irq(gp2a->irq, gp2a);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
	pr_info("err_setup_irq\n");
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	pr_info("err_sysfs_create_group_proximity\n");
	input_unregister_device(gp2a->proximity_input_dev);
err_input_allocate_device_proximity:
	pr_info("err_input_allocate_device_proximity\n");
	mutex_destroy(&gp2a->power_lock);
	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	pr_info("done\n");
	return ret;
}
コード例 #30
0
ファイル: hil_kbd.c プロジェクト: rrowicki/Chrono_Kernel-1
	input_dev->id.bustype	= BUS_HIL;
	input_dev->id.vendor	= PCI_VENDOR_ID_HP;
	input_dev->id.product	= 0x0001; /* TODO: get from kbd->rsc */
	input_dev->id.version	= 0x0100; /* TODO: get from kbd->rsc */
	input_dev->dev.parent	= &serio->dev;

	if (!dev->is_pointer) {
		serio_write(serio, 0);
		serio_write(serio, 0);
		serio_write(serio, HIL_PKT_CMD >> 8);
		/* Enable Keyswitch Autorepeat 1 */
		serio_write(serio, HIL_CMD_EK1);
		/* No need to wait for completion */
	}

	error = input_register_device(input_dev);
	if (error)
		goto bail1;

	return 0;

 bail1:
	serio_close(serio);
	serio_set_drvdata(serio, NULL);
 bail0:
	input_free_device(input_dev);
	kfree(dev);
	return error;
}

static struct serio_device_id hil_dev_ids[] = {