static int sensor_probe(struct platform_device *pdev)
{
    struct sensor_data *sensordata = NULL;
    struct input_dev *inputdev = NULL;
    int input_registered = 0, sysfs_created = 0;
    int rt;

	dbg_func_in();

    sensordata = kzalloc(sizeof(struct sensor_data), GFP_KERNEL);
    if (!sensordata) {
        rt = -ENOMEM;
        goto err;
    }

	atomic_set(&sensordata->enable, 0);
	atomic_set(&sensordata->delay, SENSOR_DEFAULT_DELAY);

    inputdev = input_allocate_device();
    if (!inputdev) {
        rt = -ENOMEM;
        printk(KERN_ERR "sensor_probe: Failed to allocate input_data device\n");
        goto err;
    }

	inputdev->name = SENSOR_INPUTDEV_NAME;
	input_set_capability(inputdev, EV_ABS, ABS_MISC);
	input_set_abs_params(inputdev, ABS_X, SENSOR_MIN_ABS, SENSOR_MAX_ABS, 0, 0);
	input_set_abs_params(inputdev, ABS_Y, SENSOR_MIN_ABS, SENSOR_MAX_ABS, 0, 0);
	input_set_abs_params(inputdev, ABS_Z, SENSOR_MIN_ABS, SENSOR_MAX_ABS, 0, 0);

    rt = input_register_device(inputdev);
    if (rt) {
        printk(KERN_ERR "sensor_probe: Unable to register input_data device: %s\n", inputdev->name);
        goto err;
    }
    input_set_drvdata(inputdev, sensordata);
    input_registered = 1;

    rt = sysfs_create_group(&inputdev->dev.kobj, &sensor_attribute_group);
    if (rt) {
        printk(KERN_ERR "sensor_probe: sysfs_create_group failed[%s]\n", inputdev->name);
        goto err;
    }
    sysfs_created = 1;

	mutex_init(&sensordata->enable_mutex);
	mutex_init(&sensordata->data_mutex);
	
	INIT_DELAYED_WORK(&sensordata->work, sensor_work_func);

	//L3G4200D_init();

	input_pdev = inputdev;

	dbg_func_out();

    return 0;

err:
    if (sensordata != NULL) {
        if (inputdev != NULL) {
            if (sysfs_created) {
                sysfs_remove_group(&inputdev->dev.kobj,
                        &sensor_attribute_group);
            }
            if (input_registered) {
                input_unregister_device(inputdev);
            }
            else {
                input_free_device(inputdev);
            }
            inputdev = NULL;
        }
        kfree(sensordata);
    }

	dbg_func_out();

    return rt;
}
Exemple #2
0
static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
{
	struct spaceball *spaceball;
	struct input_dev *input_dev;
	int err = -ENOMEM;
	int i, id;

	if ((id = serio->id.id) > SPACEBALL_MAX_ID)
		return -ENODEV;

	spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!spaceball || !input_dev)
		goto fail1;

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

	input_dev->name = spaceball_names[id];
	input_dev->phys = spaceball->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->id.vendor = SERIO_SPACEBALL;
	input_dev->id.product = id;
	input_dev->id.version = 0x0100;
	input_dev->dev.parent = &serio->dev;

	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);

	switch (id) {
		case SPACEBALL_4000FLX:
		case SPACEBALL_4000FLX_L:
			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9);
			input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
		default:
			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
				| BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
		case SPACEBALL_3003C:
			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
	}

	for (i = 0; i < 3; i++) {
		input_set_abs_params(input_dev, ABS_X + i, -8000, 8000, 8, 40);
		input_set_abs_params(input_dev, ABS_RX + i, -1600, 1600, 2, 8);
	}

	serio_set_drvdata(serio, spaceball);

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

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

	return 0;

 fail3:	serio_close(serio);
 fail2:	serio_set_drvdata(serio, NULL);
 fail1:	input_free_device(input_dev);
	kfree(spaceball);
	return err;
}
int ibmasm_init_remote_input_dev(struct service_processor *sp)
{
	/*                               */
	struct input_dev *mouse_dev, *keybd_dev;
	struct pci_dev *pdev = to_pci_dev(sp->dev);
	int error = -ENOMEM;
	int i;

	sp->remote.mouse_dev = mouse_dev = input_allocate_device();
	sp->remote.keybd_dev = keybd_dev = input_allocate_device();

	if (!mouse_dev || !keybd_dev)
		goto err_free_devices;

	mouse_dev->id.bustype = BUS_PCI;
	mouse_dev->id.vendor = pdev->vendor;
	mouse_dev->id.product = pdev->device;
	mouse_dev->id.version = 1;
	mouse_dev->dev.parent = sp->dev;
	mouse_dev->evbit[0]  = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	mouse_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
	set_bit(BTN_TOUCH, mouse_dev->keybit);
	mouse_dev->name = "ibmasm RSA I remote mouse";
	input_set_abs_params(mouse_dev, ABS_X, 0, MOUSE_X_MAX, 0, 0);
	input_set_abs_params(mouse_dev, ABS_Y, 0, MOUSE_Y_MAX, 0, 0);

	keybd_dev->id.bustype = BUS_PCI;
	keybd_dev->id.vendor = pdev->vendor;
	keybd_dev->id.product = pdev->device;
	keybd_dev->id.version = 2;
	keybd_dev->dev.parent = sp->dev;
	keybd_dev->evbit[0]  = BIT_MASK(EV_KEY);
	keybd_dev->name = "ibmasm RSA I remote keyboard";

	for (i = 0; i < XLATE_SIZE; i++) {
		if (xlate_high[i])
			set_bit(xlate_high[i], keybd_dev->keybit);
		if (xlate[i])
			set_bit(xlate[i], keybd_dev->keybit);
	}

	error = input_register_device(mouse_dev);
	if (error)
		goto err_free_devices;

	error = input_register_device(keybd_dev);
	if (error)
		goto err_unregister_mouse_dev;

	enable_mouse_interrupts(sp);

	printk(KERN_INFO "ibmasm remote responding to events on RSA card %d\n", sp->number);

	return 0;

 err_unregister_mouse_dev:
	input_unregister_device(mouse_dev);
	mouse_dev = NULL; /*                                        */
 err_free_devices:
	input_free_device(mouse_dev);
	input_free_device(keybd_dev);

	return error;
}
Exemple #4
0
static int xenkbd_probe(struct xenbus_device *dev,
				  const struct xenbus_device_id *id)
{
	int ret, i, abs;
	struct xenkbd_info *info;
	struct input_dev *kbd, *ptr;

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure");
		return -ENOMEM;
	}
	dev_set_drvdata(&dev->dev, info);
	info->xbdev = dev;
	info->irq = -1;
	info->gref = -1;
	snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename);

	info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
	if (!info->page)
		goto error_nomem;

	if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-abs-pointer", "%d", &abs) < 0)
		abs = 0;
	if (abs)
		xenbus_printf(XBT_NIL, dev->nodename, "request-abs-pointer", "1");

	/* keyboard */
	kbd = input_allocate_device();
	if (!kbd)
		goto error_nomem;
	kbd->name = "Xen Virtual Keyboard";
	kbd->phys = info->phys;
	kbd->id.bustype = BUS_PCI;
	kbd->id.vendor = 0x5853;
	kbd->id.product = 0xffff;

	__set_bit(EV_KEY, kbd->evbit);
	for (i = KEY_ESC; i < KEY_UNKNOWN; i++)
		__set_bit(i, kbd->keybit);
	for (i = KEY_OK; i < KEY_MAX; i++)
		__set_bit(i, kbd->keybit);

	ret = input_register_device(kbd);
	if (ret) {
		input_free_device(kbd);
		xenbus_dev_fatal(dev, ret, "input_register_device(kbd)");
		goto error;
	}
	info->kbd = kbd;

	/* pointing device */
	ptr = input_allocate_device();
	if (!ptr)
		goto error_nomem;
	ptr->name = "Xen Virtual Pointer";
	ptr->phys = info->phys;
	ptr->id.bustype = BUS_PCI;
	ptr->id.vendor = 0x5853;
	ptr->id.product = 0xfffe;

	if (abs) {
		__set_bit(EV_ABS, ptr->evbit);
		input_set_abs_params(ptr, ABS_X, 0, XENFB_WIDTH, 0, 0);
		input_set_abs_params(ptr, ABS_Y, 0, XENFB_HEIGHT, 0, 0);
	} else {
		input_set_capability(ptr, EV_REL, REL_X);
		input_set_capability(ptr, EV_REL, REL_Y);
	}
	input_set_capability(ptr, EV_REL, REL_WHEEL);

	__set_bit(EV_KEY, ptr->evbit);
	for (i = BTN_LEFT; i <= BTN_TASK; i++)
		__set_bit(i, ptr->keybit);

	ret = input_register_device(ptr);
	if (ret) {
		input_free_device(ptr);
		xenbus_dev_fatal(dev, ret, "input_register_device(ptr)");
		goto error;
	}
	info->ptr = ptr;

	ret = xenkbd_connect_backend(dev, info);
	if (ret < 0)
		goto error;

	return 0;

 error_nomem:
	ret = -ENOMEM;
	xenbus_dev_fatal(dev, ret, "allocating device memory");
 error:
	xenkbd_remove(dev);
	return ret;
}
static int __devinit egalax_ts_probe(struct i2c_client *client,
				       const struct i2c_device_id *id)
{
	struct egalax_ts *data;
	struct input_dev *input_dev;
	int ret;

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

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

	data->client = client;
	data->input_dev = input_dev;
	/* controller may be in sleep, wake it up. */
	if (egalax_wake_up_device(client) != 0) {
		dev_info(&client->dev, "Failed to wake up, disable suspend,"
			 " otherwise it can not wake up\n");
		data->touch_no_wake = true;
	}
	msleep(10);
	/* the controller needs some time to wakeup, otherwise the
	 * following firmware version read will be failed.
	 */
	ret = egalax_firmware_version(client);
	if (ret < 0) {
		dev_err(&client->dev,
			"egalax_ts: failed to read firmware version\n");
		ret = -EIO;
		goto err_free_dev;
	}

	input_dev->name = "eGalax Touch Screen";
	input_dev->id.bustype = BUS_I2C;
	input_dev->dev.parent = &client->dev;

	__set_bit(EV_ABS, input_dev->evbit);

	input_set_abs_params(input_dev,
			     ABS_MT_POSITION_X, 0, EGALAX_MAX_X, 0, 0);
	input_set_abs_params(input_dev,
			     ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0);
	input_set_abs_params(input_dev,
			     ABS_MT_PRESSURE, 0, EGALAX_MAX_Z, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 1, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0,
					MAX_SUPPORT_POINTS-1, 0, 0);

	input_set_drvdata(input_dev, data);

	ret = request_threaded_irq(client->irq, NULL, egalax_ts_interrupt,
					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
					"egalax_ts", data);
	if (ret < 0) {
		dev_err(&client->dev, "Failed to register interrupt\n");
		goto err_free_dev;
	}

	ret = input_register_device(data->input_dev);
	if (ret < 0)
		goto err_free_irq;
	i2c_set_clientdata(client, data);

#ifdef CONFIG_EARLYSUSPEND
	/* Not register earlysuspend if not way to wake device. */
	if (data->touch_no_wake == false) {
		/* register this client's earlysuspend */
		data->es_handler.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
		data->es_handler.suspend = egalax_early_suspend;
		data->es_handler.resume = egalax_later_resume;
		data->es_handler.data = (void *)client;
		register_early_suspend(&data->es_handler);
	}
#endif

	return 0;

err_free_irq:
	free_irq(client->irq, data);
err_free_dev:
	input_free_device(input_dev);
err_free_data:
	kfree(data);

	return ret;
}
static int __devinit rotary_encoder_probe(struct platform_device *pdev)
{
	struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
	struct rotary_encoder *encoder;
	struct input_dev *input;
	int err;

	if (!pdata) {
		dev_err(&pdev->dev, "missing platform data\n");
		return -ENOENT;
	}

	encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL);
	input = input_allocate_device();
	if (!encoder || !input) {
		dev_err(&pdev->dev, "failed to allocate memory for device\n");
		err = -ENOMEM;
		goto exit_free_mem;
	}

	encoder->input = input;
	encoder->pdata = pdata;
	encoder->irq_a = gpio_to_irq(pdata->gpio_a);
	encoder->irq_b = gpio_to_irq(pdata->gpio_b);

	/* create and register the input driver */
	input->name = pdev->name;
	input->id.bustype = BUS_HOST;
	input->dev.parent = &pdev->dev;

	if (pdata->relative_axis) {
		input->evbit[0] = BIT_MASK(EV_REL);
		input->relbit[0] = BIT_MASK(pdata->axis);
	} else {
		input->evbit[0] = BIT_MASK(EV_ABS);
		input_set_abs_params(encoder->input,
				     pdata->axis, 0, pdata->steps, 0, 1);
	}

	err = input_register_device(input);
	if (err) {
		dev_err(&pdev->dev, "failed to register input device\n");
		goto exit_free_mem;
	}

	/* request the GPIOs */
	err = gpio_request(pdata->gpio_a, DRV_NAME);
	if (err) {
		dev_err(&pdev->dev, "unable to request GPIO %d\n",
			pdata->gpio_a);
		goto exit_unregister_input;
	}

	err = gpio_request(pdata->gpio_b, DRV_NAME);
	if (err) {
		dev_err(&pdev->dev, "unable to request GPIO %d\n",
			pdata->gpio_b);
		goto exit_free_gpio_a;
	}

	/* request the IRQs */
	err = request_irq(encoder->irq_a, &rotary_encoder_irq,
			  IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
			  DRV_NAME, encoder);
	if (err) {
		dev_err(&pdev->dev, "unable to request IRQ %d\n",
			encoder->irq_a);
		goto exit_free_gpio_b;
	}

	err = request_irq(encoder->irq_b, &rotary_encoder_irq,
			  IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
			  DRV_NAME, encoder);
	if (err) {
		dev_err(&pdev->dev, "unable to request IRQ %d\n",
			encoder->irq_b);
		goto exit_free_irq_a;
	}

	platform_set_drvdata(pdev, encoder);

	return 0;

exit_free_irq_a:
	free_irq(encoder->irq_a, encoder);
exit_free_gpio_b:
	gpio_free(pdata->gpio_b);
exit_free_gpio_a:
	gpio_free(pdata->gpio_a);
exit_unregister_input:
	input_unregister_device(input);
	input = NULL; /* so we don't try to free it */
exit_free_mem:
	input_free_device(input);
	kfree(encoder);
	return err;
}
Exemple #7
0
static int __devinit apds9801_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct apds9801_data *data;
	int err = 0;
#ifdef LGE_APDS9801
	struct proximity_platform_data	*pdata;
#endif

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

	data = kzalloc(sizeof(struct apds9801_data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto exit;
	}
	data->client = client;
	i2c_set_clientdata(client, data);

#ifdef LGE_APDS9801
	pdata = data->client->dev.platform_data;
	if (NULL == pdata) {
		dev_err(&client->dev, "failed to get platform data\n");
		goto exit_kfree;
	}

	data->irq = gpio_to_irq(pdata->irq_num);
	data->debounce = 0;
	data->last_vout = -1;
	
	/* power on for ALS and first i2c communication */
	pdata->power(1);
#endif 
	mutex_init(&data->update_lock);

	/* Initialize the APDS9801 chip */
	err = apds9801_init_client(client);
	if (err)
		goto exit_kfree;

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

	dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);

#ifdef LGE_APDS9801
	/* allocate input device for transfer proximity event */
	data->input_dev = input_allocate_device();
	if (NULL == data->input_dev) {
		dev_err(&client->dev, "failed to allocation\n");
		goto exit_kfree;
	}

	/* initialise input device for APDS9801 */
	data->input_dev->name = "proximity";
	//data->input_dev->phys = "proximity/input2";

	set_bit(EV_SYN, data->input_dev->evbit); //for sync
	set_bit(EV_ABS, data->input_dev->evbit);
	input_set_abs_params(data->input_dev, ABS_DISTANCE, 0, 1, 0, 0);

	/* register input device for APDS9801 */
	err = input_register_device(data->input_dev);
	if (err < 0) {
		dev_err(&client->dev, "failed to register input\n");
		goto err_input_register_device;
	}

	device_init_wakeup(&client->dev, 1);

	spin_lock_init(&data->lock);

#endif 

	return 0;

err_irq_request:
err_input_register_device:
	input_free_device(data->input_dev);
exit_kfree:
	kfree(data);
exit:
	return err;
}
Exemple #8
0
static int pixcir_i2c_ts_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct pixcir_i2c_ts_data *tsdata;
	struct input_dev *input;
	int error = 0;
	unsigned char Wrbuf;

	error = touch_reset();
	if (error)
		goto fail;
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "i2c check functionality failed\n");
		return -ENODEV;
	}

	tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL);
	if (!tsdata) {
		dev_err(&client->dev, "failed to allocate driver data!\n");
		error = -ENOMEM;
		goto fail1;
	}

	dev_set_drvdata(&client->dev, tsdata);

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

	set_bit(EV_SYN, input->evbit);
	set_bit(EV_KEY, input->evbit);
	set_bit(EV_ABS, input->evbit);
	set_bit(BTN_TOUCH, input->keybit);
	set_bit(BTN_2, input->keybit);

	input_set_abs_params(input, ABS_X, TOUCHSCREEN_MINX,
						TOUCHSCREEN_MAXX, 0, 0);
	input_set_abs_params(input, ABS_Y, TOUCHSCREEN_MINY,
						TOUCHSCREEN_MAXY, 0, 0);
	input_set_abs_params(input, ABS_HAT0X, TOUCHSCREEN_MINX,
						TOUCHSCREEN_MAXX, 0, 0);
	input_set_abs_params(input, ABS_HAT0Y, TOUCHSCREEN_MINY,
						TOUCHSCREEN_MAXY, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_X, TOUCHSCREEN_MINX,
						TOUCHSCREEN_MAXX, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_Y, TOUCHSCREEN_MINY,
						TOUCHSCREEN_MAXY, 0, 0);
	input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
	input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 25, 0, 0);

	input->name = client->name;
	input->id.bustype = BUS_I2C;
	input->dev.parent = &client->dev;

	input->open = pixcir_ts_open;
	input->close = pixcir_ts_close;

	input_set_drvdata(input, tsdata);

	tsdata->client = client;
	tsdata->input = input;

	INIT_WORK(&tsdata->work.work, pixcir_ts_poscheck);

	tsdata->irq = client->irq;

	error = input_register_device(input);
	if (error) {
		dev_err(&client->dev, "Could not register input device\n");
		goto fail2;
	}

	error = gpio_request(TOUCH_INT_PIN, "GPX3");
	if (error) {
			dev_err(&client->dev, "gpio_request failed\n");
			error = -ENODEV;
			goto fail3;

	} else {
		s3c_gpio_cfgpin(TOUCH_INT_PIN, S3C_GPIO_SFN(0x0F));
		s3c_gpio_setpull(TOUCH_INT_PIN, S3C_GPIO_PULL_UP);
	}

#if defined(Unidisplay_9_7inch) || defined(Unidisplay_7inch) \
	|| defined(Unidisplay_7inch)
	Wrbuf = 0xcc;
	if (i2c_master_send(tsdata->client, &Wrbuf, 1) != 1) {
		dev_err(&client->dev, "i2c transfer failed\n");
		error = -ENODEV;
		goto fail3;
	}
#endif
	pixcir_wq = create_singlethread_workqueue("pixcir_wq");
	if (!pixcir_wq) {
		error = -ENOMEM;
		goto fail3;
	}

#ifdef NAS_7inch
	error = request_irq(tsdata->irq, pixcir_ts_isr, IRQF_DISABLED |
				IRQF_TRIGGER_FALLING, client->name, tsdata);
#elif defined Unidisplay_7inch
	error = request_irq(tsdata->irq, pixcir_ts_isr, IRQF_SAMPLE_RANDOM
				, client->name, tsdata);
#endif
	if (error) {
		dev_err(&client->dev, "Failed to request irq %d\n", \
			 tsdata->irq);
		goto fail3;
	}
	if (!error) {
		device_init_wakeup(&client->dev, 1);
		dev_info(&tsdata->client->dev, "probed successfully!\n");
		return 0;
	}
fail3:
	input_unregister_device(input);
	input = NULL;
fail2:
	kfree(tsdata);
fail1:
	dev_set_drvdata(&client->dev, NULL);
fail:
	return error;

}
static int __devinit adc_probe(struct platform_device *pdev)
{
	struct kp *kp;
	int i, ret;
	s8 phys[32];

	kp = kzalloc(sizeof(struct kp), GFP_KERNEL);
	if (!kp) {
		kfree(kp);
		return -ENOMEM;
	}
	gp_kp=kp;

	kp->circle_flag[0] = 0;
	kp->circle_flag[1] = 0;
	kp->old_x = 0;
	kp->old_y = 0;


	for (i=0; i<SARADC_CHAN_NUM; i++) {
		kp->cur_keycode[i] = 0;
		kp->cur_keycode_status[i] = 0;
		kp->tmp_code[i] = 0;
		kp->count[i] = 0;
		kp->js_flag[i] = 0;
	}

	kp->chan_num = 4;
	kp->chan[0] = CHAN_0;
	kp->chan[1] = CHAN_1;
	kp->chan[2] = CHAN_2;
	kp->chan[3] = CHAN_3;
	kp->chan[4] = CHAN_4; //KEY_VOLUMEDOWN,KEY_VOLUMEUP


	/************************************************************************************/
	//register keytouch
	kp->input_keytouch = input_allocate_device();
	if (!kp->input_keytouch) {
		printk("---------- allocate input_keytouch fail ------------\n");
		kfree(kp);
		input_free_device(kp->input_keytouch);
		return -ENOMEM;
	}

	set_bit(BTN_TOUCH, kp->input_keytouch->keybit);
	set_bit(EV_REP, kp->input_keytouch->evbit);
	set_bit(EV_KEY, kp->input_keytouch->evbit);
	set_bit(EV_ABS, kp->input_keytouch->evbit);
	set_bit(EV_SYN, kp->input_keytouch->evbit);
	set_bit(ABS_MT_TOUCH_MAJOR, kp->input_keytouch->absbit);
	set_bit(ABS_MT_WIDTH_MAJOR, kp->input_keytouch->absbit);
	set_bit(ABS_MT_POSITION_X, kp->input_keytouch->absbit);
	set_bit(ABS_MT_POSITION_Y, kp->input_keytouch->absbit);
	set_bit(ABS_MT_TRACKING_ID, kp->input_keytouch->absbit);
	input_set_abs_params(kp->input_keytouch, ABS_MT_POSITION_X, 0, LCD_SCREEN_X, 0, 0);
	input_set_abs_params(kp->input_keytouch, ABS_MT_POSITION_Y, 0, LCD_SCREEN_Y, 0, 0);
	input_set_abs_params(kp->input_keytouch, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
	input_set_abs_params(kp->input_keytouch, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
	input_set_abs_params(kp->input_keytouch, ABS_MT_TRACKING_ID, 0, TRACKING_ID, 0, 0);

	sprintf(phys, "input/ts");
	kp->input_keytouch->name = "ADC keytouch";
	kp->input_keytouch->phys = phys;
	kp->input_keytouch->dev.parent = &pdev->dev;
	kp->input_keytouch->id.bustype = BUS_ISA;
	kp->input_keytouch->id.vendor = 0x0001;
	kp->input_keytouch->id.product = 0x0001;
	kp->input_keytouch->id.version = 0x100;
	kp->input_keytouch->rep[REP_DELAY]=0xffffffff;
	kp->input_keytouch->rep[REP_PERIOD]=0xffffffff;
	kp->input_keytouch->keycodesize = sizeof(unsigned short);
	kp->input_keytouch->keycodemax = 0x1ff;

	ret = input_register_device(kp->input_keytouch);
	if (ret < 0) {
		printk(KERN_ERR "register input_keytouch device fail\n");
		kfree(kp);
		input_free_device(kp->input_keytouch);
		return -EINVAL;
	}
	/************************************************************************************/

	/************************************************************************************/
	//register joystick
	kp->input_joystick = input_allocate_device();
	if (!kp->input_joystick) {
		printk("---------- allocate input_joystick fail ------------\n");
		kfree(kp);
		input_free_device(kp->input_joystick);
		return -ENOMEM;
	}

	set_bit(KEY_VOLUMEDOWN, kp->input_joystick->keybit);
	set_bit(KEY_VOLUMEUP, kp->input_joystick->keybit);
	for (i = 0; i < keynum; i++)
		set_bit(gamekeys[i].code, kp->input_joystick->keybit);
	set_bit(EV_REP, kp->input_joystick->evbit);
	set_bit(EV_KEY, kp->input_joystick->evbit);
	set_bit(EV_ABS, kp->input_joystick->evbit);
	set_bit(EV_SYN, kp->input_joystick->evbit);
	input_set_abs_params(kp->input_joystick, ABS_X, -256, 255, 0, 0);
	input_set_abs_params(kp->input_joystick, ABS_Y, -256, 255, 0, 0);
	input_set_abs_params(kp->input_joystick, ABS_Z, -256, 255, 0, 0);
	input_set_abs_params(kp->input_joystick, ABS_RZ, -256, 255, 0, 0);

	kp->input_joystick->name = "ADC joystick";
	kp->input_joystick->rep[REP_DELAY]=0xffffffff;
	kp->input_joystick->rep[REP_PERIOD]=0xffffffff;
	kp->input_joystick->keycodesize = sizeof(unsigned short);
	kp->input_joystick->keycodemax = 0x1ff;
	ret = input_register_device(kp->input_joystick);
	if (ret < 0) {
		printk(KERN_ERR "register input_joystick device fail\n");
		kfree(kp);
		input_free_device(kp->input_joystick);
		return -EINVAL;
	}
	/************************************************************************************/

	platform_set_drvdata(pdev, kp);

	gpio_init();

	register_keypad_dev(gp_kp);
	struct device *dev = &pdev->dev;
	sysfs_create_group(&dev->kobj, &key_attr_group);

	INIT_WORK(&(kp->work_update), update_work_func);
	setup_timer(&kp->timer, kp_timer_sr, kp) ;
	mod_timer(&kp->timer, jiffies+msecs_to_jiffies(100));

	return 0;
}
Exemple #10
0
static int wacom_i2c_probe(struct i2c_client *client,
			   const struct i2c_device_id *id)
{
	struct wacom_g5_platform_data *pdata = client->dev.platform_data;
	struct wacom_i2c *wac_i2c;
	struct input_dev *input;
	int ret = 0;

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

	/*Check I2C functionality */
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		printk(KERN_ERR "[E-PEN] 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 "[E-PEN] failed to allocate wac_i2c.\n");
		ret = -ENOMEM;
		goto err_freemem;
	}

	input = input_allocate_device();
	if (NULL == input) {
		printk(KERN_ERR "[E-PEN] failed to allocate input device.\n");
		ret = -ENOMEM;
		goto err_input_allocate_device;
	} else
		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;
#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;

	/*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();

#if defined(CONFIG_MACH_Q1_BD)
	/* Change Origin offset by rev */
	if (system_rev < 6) {
		origin_offset[0] = origin_offset_48[0];
		origin_offset[1] = origin_offset_48[1];
	}
	/* Reset IC */
	wacom_i2c_reset_hw(wac_i2c->wac_pdata);
#endif

#if defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_P4NOTE)
	wac_i2c->wac_pdata->resume_platform_hw();
	msleep(200);
#endif

	ret = wacom_i2c_query(wac_i2c);

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

	INIT_WORK(&wac_i2c->update_work, update_work_func);

#if defined(CONFIG_MACH_P4NOTE)
	if (pdata->xy_switch) {
		input_set_abs_params(input, ABS_X, WACOM_POSY_OFFSET,
				     wac_i2c->wac_feature->y_max, 4, 0);
		input_set_abs_params(input, ABS_Y, WACOM_POSX_OFFSET,
				     wac_i2c->wac_feature->x_max, 4, 0);
	} else {
		input_set_abs_params(input, ABS_X, WACOM_POSX_OFFSET,
				     wac_i2c->wac_feature->x_max, 4, 0);
		input_set_abs_params(input, ABS_Y, WACOM_POSY_OFFSET,
				     wac_i2c->wac_feature->y_max, 4, 0);
	}
	input_set_abs_params(input, ABS_PRESSURE, 0,
			     wac_i2c->wac_feature->pressure_max, 0, 0);
#else
	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);
#endif
	input_set_drvdata(input, wac_i2c);

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

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

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

	/*Initializing for semaphor */
	mutex_init(&wac_i2c->lock);
	wake_lock_init(&wac_i2c->wakelock, WAKE_LOCK_SUSPEND, "wacom");
	INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work);
#if defined(WACOM_IRQ_WORK_AROUND)
	INIT_DELAYED_WORK(&wac_i2c->pendct_dwork, wacom_i2c_pendct_work);
#endif

	/*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) {
			printk(KERN_ERR
			       "[E-PEN]: failed to request irq(%d) - %d\n",
			       wac_i2c->irq, ret);
			goto err_request_irq;
		}

#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 err_request_irq;
		}
#endif
	}
#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");
	else {
		dev_set_drvdata(wac_i2c->dev, wac_i2c);
		ret = sysfs_create_group(&wac_i2c->dev->kobj, &epen_attr_group);
		if (ret) {
			printk(KERN_ERR
			       "[E-PEN]: failed to create sysfs group\n");
			goto err_sysfs_create_group;
		}
	}

	/* firmware info */
	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);

#ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK
	INIT_DELAYED_WORK(&wac_i2c->dvfs_work, free_dvfs_lock);
	if (exynos_cpufreq_get_level(500000, &wac_i2c->cpufreq_level))
		printk(KERN_ERR "[E-PEN] exynos_cpufreq_get_level Error\n");
#ifdef SEC_BUS_LOCK
	wac_i2c->dvfs_lock_status = false;
#if defined(CONFIG_MACH_P4NOTE)
	wac_i2c->bus_dev = dev_get("exynos-busfreq");
#endif	/* CONFIG_MACH_P4NOTE */
#endif	/* SEC_BUS_LOCK */
#endif	/* CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK */

	return 0;

 err_sysfs_create_group:
	free_irq(wac_i2c->irq, wac_i2c);
#ifdef WACOM_PDCT_WORK_AROUND
	free_irq(wac_i2c->irq_pdct, wac_i2c);
#endif
 err_request_irq:
 err_register_device:
	input_unregister_device(input);
	input = NULL;
 err_input_allocate_device:
	input_free_device(input);
 err_freemem:
	kfree(wac_i2c);
 err_i2c_fail:
	return ret;
}
Exemple #11
0
static int melfas_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct melfas_ts_data *ts;
	struct melfas_tsi_platform_data *data;
#ifdef SEC_TSP
	struct device *sec_touchscreen;
	struct device *qt602240_noise_test;
	char lcd_id, *temp;
#endif

	int ret = 0, i; 
	
	uint8_t buf[4] = {0,};
	
#if DEBUG_PRINT
	printk(KERN_ERR "%s start.\n", __func__);
#endif

    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
    {
        printk(KERN_ERR "%s: need I2C_FUNC_I2C\n", __func__);
        ret = -ENODEV;
        goto err_check_functionality_failed;
    }

    ts = kmalloc(sizeof(struct melfas_ts_data), GFP_KERNEL);
    if (ts == NULL)
    {
        printk(KERN_ERR "%s: failed to create a state of melfas-ts\n", __func__);
        ret = -ENOMEM;
        goto err_alloc_data_failed;
    }
	ts_data = ts;
	data = client->dev.platform_data;
	ts->power = data->power;
	ts->gpio = data->gpio;
    ts->client = client;
    i2c_set_clientdata(client, ts);
	ts->power(true);
    ret = i2c_master_send(ts->client, &buf, 1);


#if DEBUG_PRINT
	printk(KERN_ERR "%s: i2c_master_send() [%d], Add[%d]\n", __func__, ret, ts->client->addr);
#endif



#if SET_DOWNLOAD_BY_GPIO
	buf[0] = TS_READ_VERSION_ADDR;
	ret = i2c_master_send(ts->client, &buf, 1);
	if(ret < 0)
	{
		printk(KERN_ERR "%s: i2c_master_send [%d]\n", __func__, ret);			
	}

	ret = i2c_master_recv(ts->client, &buf, 4);
	if(ret < 0)
	{
		printk(KERN_ERR "%s: i2c_master_recv [%d]\n", __func__, ret);			
	}
	printk(KERN_ERR "FW_VERSION: 0x%02x\n", buf[3]);

	temp = get_s6e8aa0_id_buffer();
	lcd_id = *(temp+1);
	printk(KERN_ERR "LCD_ID : 0x%02x 0x%02x\n", *temp, lcd_id);

	if(lcd_id != 0x23 && lcd_id != 0x80 && buf[3] < FW_VERSION)
	{
		printk(KERN_ERR "FW Upgrading... FW_VERSION: 0x%02x\n", buf[3]);
		ret = mcsdl_download_binary_data(data);		
		if(ret == 0)
		{
			printk(KERN_ERR "SET Download Fail - error code [%d]\n", ret);			
		}
	}	
#endif // SET_DOWNLOAD_BY_GPIO
	
	ts->input_dev = input_allocate_device();
    if (!ts->input_dev)
    {
		printk(KERN_ERR "%s: Not enough memory\n", __func__);
		ret = -ENOMEM;
		goto err_input_dev_alloc_failed;
	} 

	ts->input_dev->name = "sec_touchscreen" ;

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

	ts->input_dev->keybit[BIT_WORD(KEY_MENU)] |= BIT_MASK(KEY_MENU);
	ts->input_dev->keybit[BIT_WORD(KEY_HOME)] |= BIT_MASK(KEY_HOME);
	ts->input_dev->keybit[BIT_WORD(KEY_BACK)] |= BIT_MASK(KEY_BACK);		
	ts->input_dev->keybit[BIT_WORD(KEY_SEARCH)] |= BIT_MASK(KEY_SEARCH);			


//	__set_bit(BTN_TOUCH, ts->input_dev->keybit);
//	__set_bit(EV_ABS,  ts->input_dev->evbit);
//	ts->input_dev->evbit[0] =  BIT_MASK(EV_SYN) | BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);	

	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, TS_MAX_X_COORD, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, TS_MAX_Y_COORD, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, TS_MAX_Z_TOUCH, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, 0, MELFAS_MAX_TOUCH-1, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, TS_MAX_W_TOUCH, 0, 0);
//	__set_bit(EV_SYN, ts->input_dev->evbit); 
//	__set_bit(EV_KEY, ts->input_dev->evbit);	


    ret = input_register_device(ts->input_dev);
    if (ret)
    {
        printk(KERN_ERR "%s: Failed to register device\n", __func__);
        ret = -ENOMEM;
        goto err_input_register_device_failed;
    }

    if (ts->client->irq)
    {
#if DEBUG_PRINT
        printk(KERN_ERR "%s: trying to request irq: %s-%d\n", __func__, ts->client->name, ts->client->irq);
#endif
		ret = request_threaded_irq(client->irq, NULL, melfas_ts_irq_handler, IRQF_ONESHOT | IRQF_TRIGGER_LOW, ts->client->name, ts);
        if (ret > 0)
        {
            printk(KERN_ERR "%s: Can't allocate irq %d, ret %d\n", __func__, ts->client->irq, ret);
            ret = -EBUSY;
            goto err_request_irq;
        }
    }
	for (i = 0; i < MELFAS_MAX_TOUCH ; i++)  /* _SUPPORT_MULTITOUCH_ */
		g_Mtouch_info[i].strength = -1;	

	tsp_enabled = true;

#if DEBUG_PRINT	
	printk(KERN_ERR "%s: succeed to register input device\n", __func__);
#endif

#ifdef SEC_TSP
	sec_touchscreen = device_create(sec_class, NULL, 0, ts, "sec_touchscreen");
	if (IS_ERR(sec_touchscreen))
		pr_err("[TSP] Failed to create device for the sysfs\n");

	ret = sysfs_create_group(&sec_touchscreen->kobj, &sec_touch_attr_group);
	if (ret)
		pr_err("[TSP] Failed to create sysfs group\n");
#endif

#ifdef TSP_FACTORY_TEST
	qt602240_noise_test = device_create(sec_class, NULL, 0, ts, "qt602240_noise_test");
	if (IS_ERR(qt602240_noise_test))
		pr_err("[TSP] Failed to create device for the sysfs\n");

	ret = sysfs_create_group(&qt602240_noise_test->kobj, &sec_touch_factory_attr_group);
	if (ret)
		pr_err("[TSP] Failed to create sysfs group\n");
#endif

#if CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	ts->early_suspend.suspend = melfas_ts_early_suspend;
	ts->early_suspend.resume = melfas_ts_late_resume;
	register_early_suspend(&ts->early_suspend);
#endif
#ifdef SET_TSP_CONFIG
	melfas_set_config(ts->client, MIP_ACTIVE_REPORT_RATE, 60);
//	melfas_set_config(ts->client, MIP_CONTACT_ON_EVENT_THRES, 60);
//	melfas_set_config(ts->client, MIP_MOVING_EVENT_THRES, 20);
//	melfas_set_config(ts->client, MIP_POSITION_FILTER_LEVEL, 10);
#endif
#if DEBUG_PRINT
	printk(KERN_INFO "%s: Start touchscreen. name: %s, irq: %d\n", __func__, ts->client->name, ts->client->irq);
#endif
	return 0;

err_request_irq:
	printk(KERN_ERR "melfas-ts: err_request_irq failed\n");
	free_irq(client->irq, ts);
err_input_register_device_failed:
	printk(KERN_ERR "melfas-ts: err_input_register_device failed\n");
	input_free_device(ts->input_dev);
err_input_dev_alloc_failed:
	printk(KERN_ERR "melfas-ts: err_input_dev_alloc failed\n");
err_alloc_data_failed:
	printk(KERN_ERR "melfas-ts: err_alloc_data failed_\n");	
err_detect_failed:
	printk(KERN_ERR "melfas-ts: err_detect failed\n");
	kfree(ts);
err_check_functionality_failed:
	printk(KERN_ERR "melfas-ts: err_check_functionality failed_\n");

	return ret;
}
Exemple #12
0
static int __devinit mag3110_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter;
	struct input_dev *idev;
	struct mag3110_data *data;
	int ret = 0;

	adapter = to_i2c_adapter(client->dev.parent);
	if (!i2c_check_functionality(adapter,
				     I2C_FUNC_SMBUS_BYTE |
				     I2C_FUNC_SMBUS_BYTE_DATA |
				     I2C_FUNC_SMBUS_I2C_BLOCK))
		return -EIO;

	dev_info(&client->dev, "check mag3110 chip ID\n");
	ret = mag3110_read_reg(client, MAG3110_WHO_AM_I);

	if (MAG3110_ID != ret) {
		dev_err(&client->dev,
			"read chip ID 0x%x is not equal to 0x%x!\n", ret,
			MAG3110_ID);
		return -EINVAL;
	}
	data = kzalloc(sizeof(struct mag3110_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;
	data->client = client;
	i2c_set_clientdata(client, data);
	/* Init queue */
	init_waitqueue_head(&data->waitq);

	data->hwmon_dev = hwmon_device_register(&client->dev);
	if (IS_ERR(data->hwmon_dev)) {
		dev_err(&client->dev, "hwmon register failed!\n");
		ret = PTR_ERR(data->hwmon_dev);
		goto error_rm_dev_sysfs;
	}

	/*input poll device register */
	data->poll_dev = input_allocate_polled_device();
	if (!data->poll_dev) {
		dev_err(&client->dev, "alloc poll device failed!\n");
		ret = -ENOMEM;
		goto error_rm_hwmon_dev;
	}
	data->poll_dev->poll = mag3110_dev_poll;
	data->poll_dev->poll_interval = POLL_INTERVAL;
	data->poll_dev->poll_interval_max = POLL_INTERVAL_MAX;
	idev = data->poll_dev->input;
	idev->name = MAG3110_DRV_NAME;
	idev->id.bustype = BUS_I2C;
	idev->evbit[0] = BIT_MASK(EV_ABS);
	input_set_abs_params(idev, ABS_X, -15000, 15000, 0, 0);
	input_set_abs_params(idev, ABS_Y, -15000, 15000, 0, 0);
	input_set_abs_params(idev, ABS_Z, -15000, 15000, 0, 0);
	ret = input_register_polled_device(data->poll_dev);
	if (ret) {
		dev_err(&client->dev, "register poll device failed!\n");
		goto error_free_poll_dev;
	}

	/*create device group in sysfs as user interface */
	ret = sysfs_create_group(&idev->dev.kobj, &mag3110_attr_group);
	if (ret) {
		dev_err(&client->dev, "create device file failed!\n");
		ret = -EINVAL;
		goto error_rm_poll_dev;
	}
	/* set irq type to edge rising */
#if MAG3110_IRQ_USED
	ret = request_irq(client->irq, mag3110_irq_handler,
			  IRQF_TRIGGER_RISING, client->dev.driver->name, idev);
	if (ret < 0) {
		dev_err(&client->dev, "failed to register irq %d!\n",
			client->irq);
		goto error_rm_dev_sysfs;
	}
#endif
	/* Initialize mag3110 chip */
	mag3110_init_client(client);
	mag3110_pdata = data;
	mag3110_pdata->active = MAG_STANDBY;
	mag3110_pdata->position = *(int *)client->dev.platform_data;
	dev_info(&client->dev, "mag3110 is probed\n");
	return 0;
error_rm_dev_sysfs:
	sysfs_remove_group(&client->dev.kobj, &mag3110_attr_group);
error_rm_poll_dev:
	input_unregister_polled_device(data->poll_dev);
error_free_poll_dev:
	input_free_polled_device(data->poll_dev);
error_rm_hwmon_dev:
	hwmon_device_unregister(data->hwmon_dev);

	kfree(data);
	mag3110_pdata = NULL;

	return ret;
}
Exemple #13
0
static int __devinit msm_ts_probe(struct platform_device *pdev)
{
	struct msm_ts_platform_data *pdata = pdev->dev.platform_data;
	struct msm_ts *ts;
	struct resource *tssc_res;
	struct resource *irq1_res;
	struct resource *irq2_res;
	int err = 0;
	int i;
	struct marimba_tsadc_client *ts_client;

	printk("%s\n", __func__);

	tssc_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tssc");
	irq1_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tssc1");
	irq2_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tssc2");

	if (!tssc_res || !irq1_res || !irq2_res) {
		pr_err("%s: required resources not defined\n", __func__);
		return -ENODEV;
	}

	if (pdata == NULL) {
		pr_err("%s: missing platform_data\n", __func__);
		return -ENODEV;
	}

	ts = kzalloc(sizeof(struct msm_ts), GFP_KERNEL);
	if (ts == NULL) {
		pr_err("%s: No memory for struct msm_ts\n", __func__);
		return -ENOMEM;
	}
	ts->pdata = pdata;
	ts->dev	  = &pdev->dev;

	ts->sample_irq = irq1_res->start;
	ts->pen_up_irq = irq2_res->start;

	ts->tssc_base = ioremap(tssc_res->start, resource_size(tssc_res));
	if (ts->tssc_base == NULL) {
		pr_err("%s: Can't ioremap region (0x%08x - 0x%08x)\n", __func__,
		       (uint32_t)tssc_res->start, (uint32_t)tssc_res->end);
		err = -ENOMEM;
		goto err_ioremap_tssc;
	}

	ts_client = marimba_tsadc_register(pdev, 1);
	if (IS_ERR(ts_client)) {
		pr_err("%s: Unable to register with TSADC\n", __func__);
		err = -ENOMEM;
		goto err_tsadc_register;
	}
	ts->ts_client = ts_client;

	err = marimba_tsadc_start(ts_client);
	if (err) {
		pr_err("%s: Unable to start TSADC\n", __func__);
		err = -EINVAL;
		goto err_start_tsadc;
	}

	ts->input_dev = input_allocate_device();
	if (ts->input_dev == NULL) {
		pr_err("failed to allocate touchscreen input device\n");
		err = -ENOMEM;
		goto err_alloc_input_dev;
	}
	ts->input_dev->name = "msm-touchscreen";
	ts->input_dev->dev.parent = &pdev->dev;

	input_set_drvdata(ts->input_dev, ts);

	input_set_capability(ts->input_dev, EV_KEY, BTN_TOUCH);
	set_bit(EV_ABS, ts->input_dev->evbit);

	input_set_abs_params(ts->input_dev, ABS_X, pdata->min_x, pdata->max_x,
			     0, 0);
	input_set_abs_params(ts->input_dev, ABS_Y, pdata->min_y, pdata->max_y,
			     0, 0);
	input_set_abs_params(ts->input_dev, ABS_PRESSURE, pdata->min_press,
			     pdata->max_press, 0, 0);

	for (i = 0; pdata->vkeys_x && (i < pdata->vkeys_x->num_keys); ++i)
		input_set_capability(ts->input_dev, EV_KEY,
				     pdata->vkeys_x->keys[i].key);
	for (i = 0; pdata->vkeys_y && (i < pdata->vkeys_y->num_keys); ++i)
		input_set_capability(ts->input_dev, EV_KEY,
				     pdata->vkeys_y->keys[i].key);

	err = input_register_device(ts->input_dev);
	if (err != 0) {
		pr_err("%s: failed to register input device\n", __func__);
		goto err_input_dev_reg;
	}

	msm_ts_hw_init(ts);

	err = request_irq(ts->sample_irq, msm_ts_irq,
			  (irq1_res->flags & ~IORESOURCE_IRQ) | IRQF_DISABLED,
			  "msm_touchscreen", ts);
	if (err != 0) {
		pr_err("%s: Cannot register irq1 (%d)\n", __func__, err);
		goto err_request_irq1;
	}

	err = request_irq(ts->pen_up_irq, msm_ts_irq,
			  (irq2_res->flags & ~IORESOURCE_IRQ) | IRQF_DISABLED,
			  "msm_touchscreen", ts);
	if (err != 0) {
		pr_err("%s: Cannot register irq2 (%d)\n", __func__, err);
		goto err_request_irq2;
	}

	platform_set_drvdata(pdev, ts);

#ifdef CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
						TSSC_SUSPEND_LEVEL;
	ts->early_suspend.suspend = msm_ts_early_suspend;
	ts->early_suspend.resume = msm_ts_late_resume;
	register_early_suspend(&ts->early_suspend);
#endif

	device_init_wakeup(&pdev->dev, pdata->can_wakeup);
	pr_info("%s: tssc_base=%p irq1=%d irq2=%d\n", __func__,
		ts->tssc_base, (int)ts->sample_irq, (int)ts->pen_up_irq);
	dump_tssc_regs(ts);
	return 0;

err_request_irq2:
	free_irq(ts->sample_irq, ts);

err_request_irq1:
	/* disable the tssc */
	tssc_writel(ts, TSSC_CTL_ENABLE, TSSC_CTL);

err_input_dev_reg:
	input_set_drvdata(ts->input_dev, NULL);
	input_free_device(ts->input_dev);

err_alloc_input_dev:
err_start_tsadc:
	marimba_tsadc_unregister(ts->ts_client);

err_tsadc_register:
	iounmap(ts->tssc_base);

err_ioremap_tssc:
	kfree(ts);
	return err;
}
Exemple #14
0
static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
		struct hid_field *field, struct hid_usage *usage,
		unsigned long **bit, int *max)
{
	struct mt_device *td = hid_get_drvdata(hdev);
	struct mt_class *cls = &td->mtclass;
	int code;

	/* Only map fields from TouchScreen or TouchPad collections.
	* We need to ignore fields that belong to other collections
	* such as Mouse that might have the same GenericDesktop usages. */
	if (field->application == HID_DG_TOUCHSCREEN)
		set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
	else if (field->application != HID_DG_TOUCHPAD)
		return 0;

	/* In case of an indirect device (touchpad), we need to add
	 * specific BTN_TOOL_* to be handled by the synaptics xorg
	 * driver.
	 * We also consider that touchscreens providing buttons are touchpads.
	 */
	if (field->application == HID_DG_TOUCHPAD ||
	    (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON ||
	    cls->is_indirect) {
		set_bit(INPUT_PROP_POINTER, hi->input->propbit);
		set_bit(BTN_TOOL_FINGER, hi->input->keybit);
		set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit);
		set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit);
		set_bit(BTN_TOOL_QUADTAP, hi->input->keybit);
	}

	/* eGalax devices provide a Digitizer.Stylus input which overrides
	 * the correct Digitizers.Finger X/Y ranges.
	 * Let's just ignore this input. */
	if (field->physical == HID_DG_STYLUS)
		return -1;

	switch (usage->hid & HID_USAGE_PAGE) {

	case HID_UP_GENDESK:
		switch (usage->hid) {
		case HID_GD_X:
			hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_POSITION_X);
			set_abs(hi->input, ABS_MT_POSITION_X, field,
				cls->sn_move);
			/* touchscreen emulation */
			set_abs(hi->input, ABS_X, field, cls->sn_move);
			mt_store_field(usage, td, hi);
			td->last_field_index = field->index;
			return 1;
		case HID_GD_Y:
			hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_POSITION_Y);
			set_abs(hi->input, ABS_MT_POSITION_Y, field,
				cls->sn_move);
			/* touchscreen emulation */
			set_abs(hi->input, ABS_Y, field, cls->sn_move);
			mt_store_field(usage, td, hi);
			td->last_field_index = field->index;
			return 1;
		}
		return 0;

	case HID_UP_DIGITIZER:
		switch (usage->hid) {
		case HID_DG_INRANGE:
			mt_store_field(usage, td, hi);
			td->last_field_index = field->index;
			return 1;
		case HID_DG_CONFIDENCE:
			mt_store_field(usage, td, hi);
			td->last_field_index = field->index;
			return 1;
		case HID_DG_TIPSWITCH:
			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
			input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
			mt_store_field(usage, td, hi);
			td->last_field_index = field->index;
			return 1;
		case HID_DG_CONTACTID:
			if (!td->maxcontacts)
				td->maxcontacts = MT_DEFAULT_MAXCONTACT;
			input_mt_init_slots(hi->input, td->maxcontacts);
			mt_store_field(usage, td, hi);
			td->last_field_index = field->index;
			td->touches_by_report++;
			return 1;
		case HID_DG_WIDTH:
			hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_TOUCH_MAJOR);
			set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
				cls->sn_width);
			mt_store_field(usage, td, hi);
			td->last_field_index = field->index;
			return 1;
		case HID_DG_HEIGHT:
			hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_TOUCH_MINOR);
			set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
				cls->sn_height);
			input_set_abs_params(hi->input,
					ABS_MT_ORIENTATION, 0, 1, 0, 0);
			mt_store_field(usage, td, hi);
			td->last_field_index = field->index;
			return 1;
		case HID_DG_TIPPRESSURE:
			hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_PRESSURE);
			set_abs(hi->input, ABS_MT_PRESSURE, field,
				cls->sn_pressure);
			/* touchscreen emulation */
			set_abs(hi->input, ABS_PRESSURE, field,
				cls->sn_pressure);
			mt_store_field(usage, td, hi);
			td->last_field_index = field->index;
			return 1;
		case HID_DG_CONTACTCOUNT:
			td->last_field_index = field->index;
			return 1;
		case HID_DG_CONTACTMAX:
			/* we don't set td->last_slot_field as contactcount and
			 * contact max are global to the report */
			td->last_field_index = field->index;
			return -1;
		}
		case HID_DG_TOUCH:
			/* Legacy devices use TIPSWITCH and not TOUCH.
			 * Let's just ignore this field. */
			return -1;
		/* let hid-input decide for the others */
		return 0;

	case HID_UP_BUTTON:
		code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
		hid_map_usage(hi, usage, bit, max, EV_KEY, code);
		input_set_capability(hi->input, EV_KEY, code);
		return 1;

	case 0xff000000:
		/* we do not want to map these: no input-oriented meaning */
		return -1;
	}

	return 0;
}
Exemple #15
0
static int pixcir_i2c_ts_probe(struct i2c_client *client,
					 const struct i2c_device_id *id)
{
	const struct pixcir_ts_platform_data *pdata =
			dev_get_platdata(&client->dev);
	struct device *dev = &client->dev;
	struct device_node *np = dev->of_node;
	struct pixcir_i2c_ts_data *tsdata;
	struct input_dev *input;
	int error;

	if (np && !pdata) {
		pdata = pixcir_parse_dt(dev);
		if (IS_ERR(pdata))
			return PTR_ERR(pdata);
	}

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

	if (!gpio_is_valid(pdata->gpio_attb)) {
		dev_err(dev, "Invalid gpio_attb in pdata\n");
		return -EINVAL;
	}

	if (!pdata->chip.max_fingers) {
		dev_err(dev, "Invalid max_fingers in pdata\n");
		return -EINVAL;
	}

	tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL);
	if (!tsdata)
		return -ENOMEM;

	input = devm_input_allocate_device(dev);
	if (!input) {
		dev_err(dev, "Failed to allocate input device\n");
		return -ENOMEM;
	}

	tsdata->client = client;
	tsdata->input = input;
	tsdata->pdata = pdata;

	input->name = client->name;
	input->id.bustype = BUS_I2C;
	input->open = pixcir_input_open;
	input->close = pixcir_input_close;
	input->dev.parent = &client->dev;

	__set_bit(EV_KEY, input->evbit);
	__set_bit(EV_ABS, input->evbit);
	__set_bit(BTN_TOUCH, input->keybit);
	input_set_abs_params(input, ABS_X, 0, pdata->x_max, 0, 0);
	input_set_abs_params(input, ABS_Y, 0, pdata->y_max, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);

	tsdata->max_fingers = tsdata->pdata->chip.max_fingers;
	if (tsdata->max_fingers > PIXCIR_MAX_SLOTS) {
		tsdata->max_fingers = PIXCIR_MAX_SLOTS;
		dev_info(dev, "Limiting maximum fingers to %d\n",
			 tsdata->max_fingers);
	}

	error = input_mt_init_slots(input, tsdata->max_fingers,
				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
	if (error) {
		dev_err(dev, "Error initializing Multi-Touch slots\n");
		return error;
	}

	input_set_drvdata(input, tsdata);

	error = devm_gpio_request_one(dev, pdata->gpio_attb,
				      GPIOF_DIR_IN, "pixcir_i2c_attb");
	if (error) {
		dev_err(dev, "Failed to request ATTB gpio\n");
		return error;
	}

	error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr,
					  IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
					  client->name, tsdata);
	if (error) {
		dev_err(dev, "failed to request irq %d\n", client->irq);
		return error;
	}

	/* Always be in IDLE mode to save power, device supports auto wake */
	error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE);
	if (error) {
		dev_err(dev, "Failed to set IDLE mode\n");
		return error;
	}

	/* Stop device till opened */
	error = pixcir_stop(tsdata);
	if (error)
		return error;

	error = input_register_device(input);
	if (error)
		return error;

	i2c_set_clientdata(client, tsdata);
	device_init_wakeup(&client->dev, 1);

	return 0;
}
static int goodix_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct goodix_ts *ts;
	int ret = 0;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		printk(KERN_ERR "%s: need I2C_FUNC_I2C\n", __func__);
		ret = -ENODEV;
		goto err_check_functionality_failed;
	}
	
	ts = kzalloc(sizeof(struct goodix_ts), GFP_KERNEL);
	if (ts == NULL) {
		ret = -ENOMEM;
		goto err_alloc_data_failed;
	}

	INIT_WORK(&ts->scan_work, goodix_ts_scan_work);
	ts->client = client;
	i2c_set_clientdata(client, ts);

	// TODO: add device check routine
	
	ts->input_dev = input_allocate_device();
	if (ts->input_dev == NULL) {
		ret = -ENOMEM;
		printk(KERN_ERR "%s: Failed to allocate input device\n", __func__);
		goto err_input_dev_alloc_failed;
	}

	ts->input_dev->name = "tcc-goodix-ts";

#ifdef MULTI_TOUCH_SUPPORT
	set_bit(EV_SYN, ts->input_dev->evbit);
	set_bit(EV_KEY, ts->input_dev->evbit);
	set_bit(EV_ABS, ts->input_dev->evbit);
	set_bit(BTN_TOUCH, ts->input_dev->keybit);
	set_bit(BTN_2, ts->input_dev->keybit);
	input_set_abs_params(ts->input_dev, ABS_X, 0, RESOLUTION_X, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_Y, 0, RESOLUTION_Y, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, GOODIX_TOUCH_WEIGHT_MAX, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, GOODIX_TOUCH_WEIGHT_MAX, 15, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_HAT0X, 0, RESOLUTION_X, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_HAT0Y, 0, RESOLUTION_Y, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, RESOLUTION_X, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, RESOLUTION_Y, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, GOODIX_TOUCH_WEIGHT_MAX, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, GOODIX_TOUCH_WEIGHT_MAX, 0, 0);	
#else
	ts->input_dev->evbit[0] = BIT_MASK(EV_ABS)|BIT_MASK(EV_KEY);
	ts->input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
	input_set_abs_params(ts->input_dev,ABS_X,0,RESOLUTION_X,0,0);
	input_set_abs_params(ts->input_dev,ABS_Y,0,RESOLUTION_Y,0,0);
#endif

	tcc8902_irq_hw_init();
	//Low to wakeup goodix
	goodix_wakeup_init();

	ret = goodix_init(ts->client);
	if (ret < 0)
	{
		ret = -ENXIO;
		goto exit_attach;
	}

	ret = input_register_device(ts->input_dev);
	if (ret) {
		printk(KERN_ERR "%s: Unable to register %s input device\n", __func__, ts->input_dev->name);
		goto err_input_register_device_failed;
	}

	ts->irq = TS_EINT_IRQ_NUM;
	if (request_irq(ts->irq, goodix_ts_interrupt, IRQF_DISABLED, DEVICE_NAME, ts)){
		ret = -EBUSY;
		goto exit_irq;
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.suspend 	= tcc8902_tsc_early_suspend;
	ts->early_suspend.resume 	= tcc8902_tsc_late_resume;
	ts->early_suspend.level 	= EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
	register_early_suspend(&ts->early_suspend);
#endif

	pr_info("Goodix i2c touchscreen device probe done.\n");	
	return 0;

	free_irq(ts->irq, ts);
exit_irq:
err_input_register_device_failed:
	input_free_device(ts->input_dev);
exit_attach:
err_detect_failed:
err_input_dev_alloc_failed:
	kfree(ts);
err_alloc_data_failed:
err_check_functionality_failed:
	return ret;
}
/* touch panel probe */
static int tpd_probe(struct platform_device *pdev) {
		int  touch_type = 1; // 0:R-touch, 1: Cap-touch
		int i=0;
	  TPD_DMESG("enter %s, %d\n", __FUNCTION__, __LINE__); 
	  /* Select R-Touch */
	 // if(g_tpd_drv == NULL||tpd_load_status == 0) 
#if 0
	 if(g_tpd_drv == NULL) 
	  {
	  	g_tpd_drv = &tpd_driver_list[0];
	  	/* touch_type:0: r-touch, 1: C-touch */
	  	touch_type = 0;
	  	TPD_DMESG("Generic touch panel driver\n");
	  }
	  	
    #ifdef CONFIG_HAS_EARLYSUSPEND
    MTK_TS_early_suspend_handler.suspend = g_tpd_drv->suspend;
    MTK_TS_early_suspend_handler.resume = g_tpd_drv->resume;
    register_early_suspend(&MTK_TS_early_suspend_handler);
    #endif
    #endif

    if (misc_register(&tpd_misc_device))
    {
	printk("mtk_tpd: tpd_misc_device register failed\n");
    }
	
    if((tpd=(struct tpd_device*)kmalloc(sizeof(struct tpd_device), GFP_KERNEL))==NULL) return -ENOMEM;
    memset(tpd, 0, sizeof(struct tpd_device));

    /* allocate input device */
    if((tpd->dev=input_allocate_device())==NULL) { kfree(tpd); return -ENOMEM; }
  
  //TPD_RES_X = simple_strtoul(LCM_WIDTH, NULL, 0);
  //TPD_RES_Y = simple_strtoul(LCM_HEIGHT, NULL, 0);    
  TPD_RES_X = DISP_GetScreenWidth();
    TPD_RES_Y = DISP_GetScreenHeight();

  
    printk("mtk_tpd: TPD_RES_X = %d, TPD_RES_Y = %d\n", TPD_RES_X, TPD_RES_Y);
  
    tpd_mode = TPD_MODE_NORMAL;
    tpd_mode_axis = 0;
    tpd_mode_min = TPD_RES_Y/2;
    tpd_mode_max = TPD_RES_Y;
    tpd_mode_keypad_tolerance = TPD_RES_X*TPD_RES_X/1600;
    /* struct input_dev dev initialization and registration */
    tpd->dev->name = TPD_DEVICE;
    set_bit(EV_ABS, tpd->dev->evbit);
    set_bit(EV_KEY, tpd->dev->evbit);
    set_bit(ABS_X, tpd->dev->absbit);
    set_bit(ABS_Y, tpd->dev->absbit);
    set_bit(ABS_PRESSURE, tpd->dev->absbit);
    set_bit(BTN_TOUCH, tpd->dev->keybit);
    set_bit(INPUT_PROP_DIRECT, tpd->dev->propbit);
#if 1    
  for(i = 1; i < TP_DRV_MAX_COUNT; i++)
	{
    		/* add tpd driver into list */
		if(tpd_driver_list[i].tpd_device_name != NULL)
		{
			tpd_driver_list[i].tpd_local_init();
			//msleep(1);
			if(tpd_load_status ==1) {
				TPD_DMESG("[mtk-tpd]tpd_probe, tpd_driver_name=%s\n", tpd_driver_list[i].tpd_device_name);
				g_tpd_drv = &tpd_driver_list[i];
				break;
			}
		}    
  }
	 if(g_tpd_drv == NULL) {
	 	if(tpd_driver_list[0].tpd_device_name != NULL) {
	  	g_tpd_drv = &tpd_driver_list[0];
	  	/* touch_type:0: r-touch, 1: C-touch */
	  	touch_type = 0;
	  	g_tpd_drv->tpd_local_init();
	  	TPD_DMESG("[mtk-tpd]Generic touch panel driver\n");
	  } else {
	  	TPD_DMESG("[mtk-tpd]cap touch and Generic touch both are not loaded!!\n");
	  	return 0;
	  	} 
	  }	
    #ifdef CONFIG_HAS_EARLYSUSPEND
    MTK_TS_early_suspend_handler.suspend = g_tpd_drv->suspend;
    MTK_TS_early_suspend_handler.resume = g_tpd_drv->resume;
    register_early_suspend(&MTK_TS_early_suspend_handler);
    #endif		  
#endif	  
//#ifdef TPD_TYPE_CAPACITIVE
		/* TPD_TYPE_CAPACITIVE handle */
		if(touch_type == 1){
			
		set_bit(ABS_MT_TRACKING_ID, tpd->dev->absbit);
    	set_bit(ABS_MT_TOUCH_MAJOR, tpd->dev->absbit);
    	set_bit(ABS_MT_TOUCH_MINOR, tpd->dev->absbit);
    	set_bit(ABS_MT_POSITION_X, tpd->dev->absbit);
    	set_bit(ABS_MT_POSITION_Y, tpd->dev->absbit);
        #if 0 // linux kernel update from 2.6.35 --> 3.0
    	tpd->dev->absmax[ABS_MT_POSITION_X] = TPD_RES_X;
    	tpd->dev->absmin[ABS_MT_POSITION_X] = 0;
    	tpd->dev->absmax[ABS_MT_POSITION_Y] = TPD_RES_Y;
    	tpd->dev->absmin[ABS_MT_POSITION_Y] = 0;
    	tpd->dev->absmax[ABS_MT_TOUCH_MAJOR] = 100;
    	tpd->dev->absmin[ABS_MT_TOUCH_MINOR] = 0;
#else
		input_set_abs_params(tpd->dev, ABS_MT_POSITION_X, 0, TPD_RES_X, 0, 0);
		input_set_abs_params(tpd->dev, ABS_MT_POSITION_Y, 0, TPD_RES_Y, 0, 0);
		input_set_abs_params(tpd->dev, ABS_MT_TOUCH_MAJOR, 0, 100, 0, 0);
		input_set_abs_params(tpd->dev, ABS_MT_TOUCH_MINOR, 0, 100, 0, 0);
		input_set_abs_params(tpd->dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
		input_set_abs_params(tpd->dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
		input_set_abs_params(tpd->dev, ABS_MT_WIDTH_MINOR, 0, 15, 0, 0);
#endif
    	TPD_DMESG("Cap touch panel driver\n");
  	}
//#endif
    #if 0 //linux kernel update from 2.6.35 --> 3.0
    tpd->dev->absmax[ABS_X] = TPD_RES_X;
    tpd->dev->absmin[ABS_X] = 0;
    tpd->dev->absmax[ABS_Y] = TPD_RES_Y;
    tpd->dev->absmin[ABS_Y] = 0;
	
    tpd->dev->absmax[ABS_PRESSURE] = 255;
    tpd->dev->absmin[ABS_PRESSURE] = 0;
    #else
		input_set_abs_params(tpd->dev, ABS_X, 0, TPD_RES_X, 0, 0);
		input_set_abs_params(tpd->dev, ABS_Y, 0, TPD_RES_Y, 0, 0);
		input_abs_set_res(tpd->dev, ABS_X, TPD_RES_X);
		input_abs_set_res(tpd->dev, ABS_Y, TPD_RES_Y);
		input_set_abs_params(tpd->dev, ABS_PRESSURE, 0, 255, 0, 0);

    #endif
    if(input_register_device(tpd->dev))
        TPD_DMESG("input_register_device failed.(tpd)\n");
    else
			tpd_register_flag = 1;
    /* init R-Touch */
    #if 0
	  if(touch_type == 0) 
	  {
	  	g_tpd_drv->tpd_local_init();
	  }    
		#endif
    if(g_tpd_drv->tpd_have_button)
    {
    	tpd_button_init();
    }

	if (g_tpd_drv->attrs.num)
		tpd_create_attributes(&pdev->dev, &g_tpd_drv->attrs);




#if defined(TARGET_S4)
	synaptics_init_sysfs ();

#else
	if(SEL_SYSFS == 1)
	{
		synaptics_init_sysfs ();
	}
	else if(SEL_SYSFS == 2)
	{	
		LU201x_init_sysfs ();

	}
#endif

    return 0;
}
Exemple #18
0
void x52_setup_input(struct input_dev *idev)
{
    int i;

    if (!idev) {
        return;
    }

    /*
     * Enable event inputs.
     *
     * EV_KEY for buttons (and keyboard events in the future)
     * EV_ABS for the axis
     * EV_REL for future mouse support by the mouse stick
     */
    idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);

    /* For now, map the buttons directly */
    for (i = BTN_TRIGGER_HAPPY1; i <= BTN_TRIGGER_HAPPY39; i++) {
        __set_bit(i, idev->keybit);
    }

    /* Map the axes */
    input_set_abs_params(idev, ABS_X, 0, 1023, 0, 0);
    input_set_abs_params(idev, ABS_Y, 0, 1023, 0, 0);
    input_set_abs_params(idev, ABS_RZ, 0, 1023, 0, 0);

    input_set_abs_params(idev, ABS_THROTTLE, 0, 255, 0, 0);
    input_set_abs_params(idev, ABS_RX, 0, 255, 0, 0);
    input_set_abs_params(idev, ABS_RY, 0, 255, 0, 0);
    input_set_abs_params(idev, ABS_Z, 0, 255, 0, 0);

    /* Mouse stick */
    input_set_abs_params(idev, ABS_TILT_X, 0, 15, 0, 0);
    input_set_abs_params(idev, ABS_TILT_Y, 0, 15, 0, 0);

    /* Hat switch */
    input_set_abs_params(idev, ABS_HAT0X, -1, 1, 0, 0);
    input_set_abs_params(idev, ABS_HAT0Y, -1, 1, 0, 0);
}
Exemple #19
0
static int __init hdaps_init(void)
{
	struct input_dev *idev;
	int ret;

	if (!dmi_check_system(hdaps_whitelist)) {
		printk(KERN_WARNING "hdaps: supported laptop not found!\n");
		ret = -ENODEV;
		goto out;
	}

	if (!request_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS, "hdaps")) {
		ret = -ENXIO;
		goto out;
	}

	ret = platform_driver_register(&hdaps_driver);
	if (ret)
		goto out_region;

	pdev = platform_device_register_simple("hdaps", -1, NULL, 0);
	if (IS_ERR(pdev)) {
		ret = PTR_ERR(pdev);
		goto out_driver;
	}

	ret = sysfs_create_group(&pdev->dev.kobj, &hdaps_attribute_group);
	if (ret)
		goto out_device;

	hdaps_idev = input_allocate_polled_device();
	if (!hdaps_idev) {
		ret = -ENOMEM;
		goto out_group;
	}

	hdaps_idev->poll = hdaps_mousedev_poll;
	hdaps_idev->poll_interval = HDAPS_POLL_INTERVAL;

	/* initial calibrate for the input device */
	hdaps_calibrate();

	/* initialize the input class */
	idev = hdaps_idev->input;
	idev->name = "hdaps";
	idev->dev.parent = &pdev->dev;
	idev->evbit[0] = BIT_MASK(EV_ABS);
	input_set_abs_params(idev, ABS_X,
			-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
	input_set_abs_params(idev, ABS_Y,
			-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);

	ret = input_register_polled_device(hdaps_idev);
	if (ret)
		goto out_idev;

	printk(KERN_INFO "hdaps: driver successfully loaded.\n");
	return 0;

out_idev:
	input_free_polled_device(hdaps_idev);
out_group:
	sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
out_device:
	platform_device_unregister(pdev);
out_driver:
	platform_driver_unregister(&hdaps_driver);
out_region:
	release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS);
out:
	printk(KERN_WARNING "hdaps: driver init failed (ret=%d)!\n", ret);
	return ret;
}
Exemple #20
0
static int __devinit msm_ts_probe(struct platform_device *pdev)
{
	struct msm_ts_platform_data *pdata = pdev->dev.platform_data;
	struct msm_ts *ts;
	struct resource *tssc_res;
	struct resource *irq1_res;
	struct resource *irq2_res;
	int err = 0;
	int i;

	printk("%s\n", __func__);

	tssc_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tssc");
	irq1_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tssc1");
	irq2_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tssc2");

	if (!tssc_res || !irq1_res || !irq2_res) {
		pr_err("%s: required resources not defined\n", __func__);
		return -ENODEV;
	}

	if (pdata == NULL) {
		pr_err("%s: missing platform_data\n", __func__);
		return -ENODEV;
	}

	ts = kzalloc(sizeof(struct msm_ts), GFP_KERNEL);
	if (ts == NULL) {
		pr_err("%s: No memory for struct msm_ts\n", __func__);
		return -ENOMEM;
	}
	ts->pdata = pdata;
	ts->dev	= &pdev->dev;

	ts->sample_irq = irq1_res->start;
	ts->pen_up_irq = irq2_res->start;

	ts->tssc_base = ioremap(tssc_res->start, resource_size(tssc_res));
	if (ts->tssc_base == NULL) {
		dev_err(&pdev->dev, "%s: Can't ioremap region (0x%08x - 0x%08x)\n", __func__,
		(uint32_t)tssc_res->start, (uint32_t)tssc_res->end);
		err = -ENOMEM;
		goto err_ioremap_tssc;
	}

	ts->input_dev = input_allocate_device();
	if (ts->input_dev == NULL) {
		dev_err(&pdev->dev, "failed to allocate touchscreen input device\n");
		err = -ENOMEM;
		goto err_alloc_input_dev;
	}
	ts->input_dev->name = "msm-touchscreen";
	ts->input_dev->dev.parent = &pdev->dev;

	input_set_drvdata(ts->input_dev, ts);

	input_set_capability(ts->input_dev, EV_KEY, BTN_TOUCH);
	set_bit(EV_ABS, ts->input_dev->evbit);

	input_set_abs_params(ts->input_dev, ABS_X, pdata->min_x, pdata->max_x,
			0, 0);
	input_set_abs_params(ts->input_dev, ABS_Y, pdata->min_y, pdata->max_y,
			0, 0);
	input_set_abs_params(ts->input_dev, ABS_PRESSURE, pdata->min_press,
			pdata->max_press, 0, 0);

	for (i = 0; pdata->vkeys_x && (i < pdata->vkeys_x->num_keys); ++i)
		input_set_capability(ts->input_dev, EV_KEY,
				pdata->vkeys_x->keys[i].key);
	for (i = 0; pdata->vkeys_y && (i < pdata->vkeys_y->num_keys); ++i)
		input_set_capability(ts->input_dev, EV_KEY,
				pdata->vkeys_y->keys[i].key);

	err = input_register_device(ts->input_dev);
	if (err != 0) {
		dev_err(&pdev->dev, "%s: failed to register input device\n", __func__);
		goto err_input_dev_reg;
	}

	msm_ts_hw_init(ts);

	err = request_irq(ts->sample_irq, msm_ts_irq,
			(irq1_res->flags & ~IORESOURCE_IRQ) | IRQF_DISABLED,
			DRV_NAME, ts);
	if (err != 0) {
		dev_err(&pdev->dev, "%s: Cannot register irq1 (%d)\n", __func__, err);
		goto err_request_irq1;
	}

	err = request_irq(ts->pen_up_irq, msm_ts_irq,
			(irq2_res->flags & ~IORESOURCE_IRQ) | IRQF_DISABLED,
			DRV_NAME, ts);
	if (err != 0) {
		dev_err(&pdev->dev, "%s: Cannot register irq2 (%d)\n", __func__, err);
		goto err_request_irq2;
	}

	platform_set_drvdata(pdev, ts);

	device_init_wakeup(&pdev->dev, pdata->can_wakeup);

	if (msm_tsdebug & MSM_TS_DEBUG_REGS) {
		dev_info(&pdev->dev, "%s: tssc_base=%p irq1=%d irq2=%d\n", __func__,
			ts->tssc_base, (int)ts->sample_irq, (int)ts->pen_up_irq);
		dump_tssc_regs(ts);
	}
	return 0;

err_request_irq2:
	free_irq(ts->sample_irq, ts);

err_request_irq1:
	/* disable the tssc */
	tssc_writel(ts, TSSC_CTL_ENABLE, TSSC_CTL);

err_input_dev_reg:
	input_set_drvdata(ts->input_dev, NULL);
	input_free_device(ts->input_dev);

err_alloc_input_dev:
	iounmap(ts->tssc_base);

err_ioremap_tssc:
	kfree(ts);
	return err;
}
Exemple #21
0
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;
}
Exemple #22
0
static int prepare_tsc_input_device(uint16_t ind,
				struct usf_type *usf_info,
				struct us_input_info_type *input_info,
				const char *name)
{
	int i = 0;
	int num_side_buttons = min(ARRAY_SIZE(s_button_map),
		sizeof(input_info->req_side_buttons_bitmap) *
		BITS_IN_BYTE);
	uint16_t max_side_button_bitmap = ((1 << ARRAY_SIZE(s_button_map)) - 1);
	struct input_dev *in_dev = allocate_dev(ind, name);
	if (in_dev == NULL)
		return -ENOMEM;

	if (input_info->req_side_buttons_bitmap > max_side_button_bitmap) {
		pr_err("%s: Requested side buttons[%d] exceeds max side buttons available[%d]\n",
		__func__,
		input_info->req_side_buttons_bitmap,
		max_side_button_bitmap);
		return -EINVAL;
	}

	usf_info->input_ifs[ind] = in_dev;
	usf_info->req_side_buttons_bitmap =
		input_info->req_side_buttons_bitmap;
	in_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	in_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);


	for (i = 0; i < num_side_buttons; i++)
		if (input_info->req_side_buttons_bitmap & (1 << i))
			in_dev->keybit[BIT_WORD(s_button_map[i])] |=
			BIT_MASK(s_button_map[i]);

	input_set_abs_params(in_dev, ABS_X,
			     input_info->tsc_x_dim[MIN_IND],
			     input_info->tsc_x_dim[MAX_IND],
			     0, 0);
	input_set_abs_params(in_dev, ABS_Y,
			     input_info->tsc_y_dim[MIN_IND],
			     input_info->tsc_y_dim[MAX_IND],
			     0, 0);
	input_set_abs_params(in_dev, ABS_DISTANCE,
			     input_info->tsc_z_dim[MIN_IND],
			     input_info->tsc_z_dim[MAX_IND],
			     0, 0);

	input_set_abs_params(in_dev, ABS_PRESSURE,
			     input_info->tsc_pressure[MIN_IND],
			     input_info->tsc_pressure[MAX_IND],
			     0, 0);

	input_set_abs_params(in_dev, ABS_TILT_X,
			     input_info->tsc_x_tilt[MIN_IND],
			     input_info->tsc_x_tilt[MAX_IND],
			     0, 0);
	input_set_abs_params(in_dev, ABS_TILT_Y,
			     input_info->tsc_y_tilt[MIN_IND],
			     input_info->tsc_y_tilt[MAX_IND],
			     0, 0);

	return 0;
}
/* setup which logical events to report */
static void setup_events_to_report(struct input_dev *input_dev,
				   const struct bcm5974_config *cfg)
{
	__set_bit(EV_ABS, input_dev->evbit);

	input_set_abs_params(input_dev, ABS_PRESSURE,
				0, cfg->p.dim, cfg->p.fuzz, 0);
	input_set_abs_params(input_dev, ABS_TOOL_WIDTH,
				0, cfg->w.dim, cfg->w.fuzz, 0);
	input_set_abs_params(input_dev, ABS_X,
				0, cfg->x.dim, cfg->x.fuzz, 0);
	input_set_abs_params(input_dev, ABS_Y,
				0, cfg->y.dim, cfg->y.fuzz, 0);

	/* finger touch area */
	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
			     cfg->w.devmin, cfg->w.devmax, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
			     cfg->w.devmin, cfg->w.devmax, 0, 0);
	/* finger approach area */
	input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR,
			     cfg->w.devmin, cfg->w.devmax, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR,
			     cfg->w.devmin, cfg->w.devmax, 0, 0);
	/* finger orientation */
	input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
			     -MAX_FINGER_ORIENTATION,
			     MAX_FINGER_ORIENTATION, 0, 0);
	/* finger position */
	input_set_abs_params(input_dev, ABS_MT_POSITION_X,
			     cfg->x.devmin, cfg->x.devmax, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
			     cfg->y.devmin, cfg->y.devmax, 0, 0);

	__set_bit(EV_KEY, input_dev->evbit);
	__set_bit(BTN_TOUCH, input_dev->keybit);
	__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
	__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
	__set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
	__set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
	__set_bit(BTN_LEFT, input_dev->keybit);
}
static int ecs_ctrl_ioctl(struct inode *inode, struct file *file, 
	unsigned int cmd, unsigned long arg)
{
	void __user *pa = (void __user *)arg;
	short flag;
	short delay;
	int parms[4];
	int ypr[13];

	switch (cmd) {
	case ECOMPASS_IOC_SET_MODE:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_MODE\n");               
		break;
	case ECOMPASS_IOC_SET_DELAY:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_DELAY\n");               
		if (copy_from_user(&delay, pa, sizeof(delay)))
			return -EFAULT;
		ecompass_delay = delay;
		break;
	case ECOMPASS_IOC_GET_DELAY:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_DELAY\n");               
		delay = ecompass_delay;
		if (copy_to_user(pa, &delay, sizeof(delay)))
			return -EFAULT;
		break;

	case ECOMPASS_IOC_SET_AFLAG:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_AFLAG\n");               
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&a_flag, flag);
		break;
	case ECOMPASS_IOC_GET_AFLAG:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_AFLAG\n");               
		flag = atomic_read(&a_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;
	case ECOMPASS_IOC_SET_MFLAG:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_MFLAG\n");               
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&m_flag, flag);
		break;
	case ECOMPASS_IOC_GET_MFLAG:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_MFLAG\n");               
		flag = atomic_read(&m_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;
	case ECOMPASS_IOC_SET_OFLAG:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_OFLAG\n");               
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&o_flag, flag);
		break;
	case ECOMPASS_IOC_GET_OFLAG:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_OFLAG\n");               
		flag = atomic_read(&o_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;

	case ECOMPASS_IOC_SET_PFLAG:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_PFLAG\n");               
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&p_flag, flag);

                if(flag==1)
                {
                    input_report_abs(ecs_data_device, ABS_DISTANCE, ((proximity_get_int_value() == 0)? 0:1));
                    input_sync(ecs_data_device);                    
                }
        
		break;
	case ECOMPASS_IOC_GET_PFLAG:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_PFLAG\n");               
		flag = atomic_read(&p_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;
		
	case ECOMPASS_IOC_SET_APARMS:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_APARMS\n");               
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* acceleration x-axis */
		input_set_abs_params(ecs_data_device, ABS_X, 
			parms[0], parms[1], parms[2], parms[3]);
		/* acceleration y-axis */
		input_set_abs_params(ecs_data_device, ABS_Y, 
			parms[0], parms[1], parms[2], parms[3]);
		/* acceleration z-axis */
		input_set_abs_params(ecs_data_device, ABS_Z, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_APARMS:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_APARMS\n");               
		break;
	case ECOMPASS_IOC_SET_MPARMS:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_MPARMS\n");               
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* magnetic raw x-axis */
		input_set_abs_params(ecs_data_device, ABS_HAT0X, 
			parms[0], parms[1], parms[2], parms[3]);
		/* magnetic raw y-axis */
		input_set_abs_params(ecs_data_device, ABS_HAT0Y, 
			parms[0], parms[1], parms[2], parms[3]);
		/* magnetic raw z-axis */
		input_set_abs_params(ecs_data_device, ABS_BRAKE, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_MPARMS:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_MPARMS\n");               
		break;
	case ECOMPASS_IOC_SET_OPARMS_YAW:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_OPARMS_YAW\n");               
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* orientation yaw */
		input_set_abs_params(ecs_data_device, ABS_RX, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_OPARMS_YAW:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_OPARMS_YAW\n");               
		break;
	case ECOMPASS_IOC_SET_OPARMS_PITCH:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_OPARMS_PITCH\n");               
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* orientation pitch */
		input_set_abs_params(ecs_data_device, ABS_RY, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_OPARMS_PITCH:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_OPARMS_PITCH\n");               
		break;
	case ECOMPASS_IOC_SET_OPARMS_ROLL:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_OPARMS_ROLL\n");               
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* orientation roll */
		input_set_abs_params(ecs_data_device, ABS_RZ, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_OPARMS_ROLL:
		MECSDBG("[MECS] ECOMPASS_IOC_GET_OPARMS_ROLL\n");               
		break;

	case ECOMPASS_IOC_SET_YPR:
		MECSDBG("[MECS] ECOMPASS_IOC_SET_YPR\n");        
		if (copy_from_user(ypr, pa, sizeof(ypr)))
			return -EFAULT;
		/* Report acceleration sensor information */
		if (atomic_read(&a_flag)) {
        		MECSDBG("[MECS] ECOMPASS_IOC_SET_YPR a_flag\n");                 
			input_report_abs(ecs_data_device, ABS_X, ypr[0]);
			input_report_abs(ecs_data_device, ABS_Y, ypr[1]);
			input_report_abs(ecs_data_device, ABS_Z, ypr[2]);
			input_report_abs(ecs_data_device, ABS_WHEEL, ypr[3]);
		}

		/* Report magnetic sensor information */
		if (atomic_read(&m_flag)) {
        		MECSDBG("[MECS] ECOMPASS_IOC_SET_YPR m_flag\n");                             
			input_report_abs(ecs_data_device, ABS_HAT0X, ypr[4]);
			input_report_abs(ecs_data_device, ABS_HAT0Y, ypr[5]);
			input_report_abs(ecs_data_device, ABS_BRAKE, ypr[6]);
			input_report_abs(ecs_data_device, ABS_GAS, ypr[7]);
		}

		/* Report orientation information */
		if (atomic_read(&o_flag)) {
        		MECSDBG("[MECS] ECOMPASS_IOC_SET_YPR o_flag\n");                             
			input_report_abs(ecs_data_device, ABS_RX, ypr[8]);
			input_report_abs(ecs_data_device, ABS_RY, ypr[9]);
			input_report_abs(ecs_data_device, ABS_RZ, ypr[10]);
			input_report_abs(ecs_data_device, ABS_RUDDER, ypr[11]);
		}

		/* Report proximity information */
		if (atomic_read(&p_flag)) {
        		MECSDBG("[MECS] ECOMPASS_IOC_SET_YPR p_flag\n");                             
#if defined(CONFIG_SENSORS_TAOS)            
			ypr[12] = taos_get_proximity_value();
#else
			ypr[12] = gp2a_get_proximity_value();
#endif

			MECSDBG("[MECS] Proximity = %d\n", ypr[12]);

			input_report_abs(ecs_data_device, ABS_DISTANCE, ypr[12]);
		}

		input_sync(ecs_data_device);
		break;

	default:
		break;
	}

	return 0;
}
static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
		struct hid_field *field, struct hid_usage *usage,
		unsigned long **bit, int *max)
{
	struct mt_device *td = hid_get_drvdata(hdev);
	struct mt_class *cls = &td->mtclass;
	int code;
	struct hid_usage *prev_usage = NULL;

	if (field->application == HID_DG_TOUCHSCREEN)
		td->mt_flags |= INPUT_MT_DIRECT;

	/*
	 * Model touchscreens providing buttons as touchpads.
	 */
	if (field->application == HID_DG_TOUCHPAD ||
	    (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON)
		td->mt_flags |= INPUT_MT_POINTER;

	/* Only map fields from TouchScreen or TouchPad collections.
         * We need to ignore fields that belong to other collections
         * such as Mouse that might have the same GenericDesktop usages. */
	if (field->application == HID_DG_TOUCHSCREEN)
		set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
	else if (field->application == HID_DG_TOUCHPAD)
		set_bit(INPUT_PROP_POINTER, hi->input->propbit);
	else
		return 0;

	if (usage->usage_index)
		prev_usage = &field->usage[usage->usage_index - 1];

	switch (usage->hid & HID_USAGE_PAGE) {

	case HID_UP_GENDESK:
		switch (usage->hid) {
		case HID_GD_X:
			if (prev_usage && (prev_usage->hid == usage->hid)) {
				hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_TOOL_X);
				set_abs(hi->input, ABS_MT_TOOL_X, field,
					cls->sn_move);
			} else {
				hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_POSITION_X);
				set_abs(hi->input, ABS_MT_POSITION_X, field,
					cls->sn_move);
			}

			mt_store_field(usage, td, hi);
			return 1;
		case HID_GD_Y:
			if (prev_usage && (prev_usage->hid == usage->hid)) {
				hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_TOOL_Y);
				set_abs(hi->input, ABS_MT_TOOL_Y, field,
					cls->sn_move);
			} else {
				hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_POSITION_Y);
				set_abs(hi->input, ABS_MT_POSITION_Y, field,
					cls->sn_move);
			}

			mt_store_field(usage, td, hi);
			return 1;
		}
		return 0;

	case HID_UP_DIGITIZER:
		switch (usage->hid) {
		case HID_DG_INRANGE:
			if (cls->quirks & MT_QUIRK_HOVERING) {
				hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_DISTANCE);
				input_set_abs_params(hi->input,
					ABS_MT_DISTANCE, 0, 1, 0, 0);
			}
			mt_store_field(usage, td, hi);
			return 1;
		case HID_DG_CONFIDENCE:
			mt_store_field(usage, td, hi);
			return 1;
		case HID_DG_TIPSWITCH:
			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
			input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
			mt_store_field(usage, td, hi);
			return 1;
		case HID_DG_CONTACTID:
			mt_store_field(usage, td, hi);
			td->touches_by_report++;
			td->mt_report_id = field->report->id;
			return 1;
		case HID_DG_WIDTH:
			hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_TOUCH_MAJOR);
			if (!(cls->quirks & MT_QUIRK_NO_AREA))
				set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
					cls->sn_width);
			mt_store_field(usage, td, hi);
			return 1;
		case HID_DG_HEIGHT:
			hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_TOUCH_MINOR);
			if (!(cls->quirks & MT_QUIRK_NO_AREA)) {
				set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
					cls->sn_height);
				input_set_abs_params(hi->input,
					ABS_MT_ORIENTATION, 0, 1, 0, 0);
			}
			mt_store_field(usage, td, hi);
			return 1;
		case HID_DG_TIPPRESSURE:
			hid_map_usage(hi, usage, bit, max,
					EV_ABS, ABS_MT_PRESSURE);
			set_abs(hi->input, ABS_MT_PRESSURE, field,
				cls->sn_pressure);
			mt_store_field(usage, td, hi);
			return 1;
		case HID_DG_CONTACTCOUNT:
			td->cc_index = field->index;
			td->cc_value_index = usage->usage_index;
			return 1;
		case HID_DG_CONTACTMAX:
			/* we don't set td->last_slot_field as contactcount and
			 * contact max are global to the report */
			return -1;
		case HID_DG_TOUCH:
			/* Legacy devices use TIPSWITCH and not TOUCH.
			 * Let's just ignore this field. */
			return -1;
		}
		/* let hid-input decide for the others */
		return 0;

	case HID_UP_BUTTON:
		code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
		hid_map_usage(hi, usage, bit, max, EV_KEY, code);
		input_set_capability(hi->input, EV_KEY, code);
		return 1;

	case 0xff000000:
		/* we do not want to map these: no input-oriented meaning */
		return -1;
	}

	return 0;
}
static int __init ecompass_init(void)
{
	int res = 0;

	printk(KERN_INFO "[MECS] ecompass driver: init\n");

	ecs_data_device = input_allocate_device();
	if (!ecs_data_device) {
		res = -ENOMEM;
		pr_err("%s: failed to allocate input device\n", __FUNCTION__);
		goto out;
	}

	set_bit(EV_ABS, ecs_data_device->evbit);

	/* 32768 == 1g, range -4g ~ +4g */
	/* acceleration x-axis */
	input_set_abs_params(ecs_data_device, ABS_X, 
		-32768*4, 32768*4, 0, 0);
	/* acceleration y-axis */
	input_set_abs_params(ecs_data_device, ABS_Y, 
		-32768*4, 32768*4, 0, 0);
	/* acceleration z-axis */
	input_set_abs_params(ecs_data_device, ABS_Z, 
		-32768*4, 32768*4, 0, 0);
	/* acceleration status, 0 ~ 3 */
	input_set_abs_params(ecs_data_device, ABS_WHEEL, 
		0, 100, 0, 0);

	/* 32768 == 1gauss, range -4gauss ~ +4gauss */
	/* magnetic raw x-axis */
	input_set_abs_params(ecs_data_device, ABS_HAT0X, 
		-32768*4, 32768*4, 0, 0);
	/* magnetic raw y-axis */
	input_set_abs_params(ecs_data_device, ABS_HAT0Y, 
		-32768*4, 32768*4, 0, 0);
	/* magnetic raw z-axis */
	input_set_abs_params(ecs_data_device, ABS_BRAKE, 
		-32768*4, 32768*4, 0, 0);
	/* magnetic raw status, 0 ~ 3 */
	input_set_abs_params(ecs_data_device, ABS_GAS, 
		0, 100, 0, 0);

	/* 65536 == 360degree */
	/* orientation yaw, 0 ~ 360 */
	input_set_abs_params(ecs_data_device, ABS_RX, 
		0, 65536, 0, 0);
	/* orientation pitch, -180 ~ 180 */
	input_set_abs_params(ecs_data_device, ABS_RY, 
		-65536/2, 65536/2, 0, 0);
	/* orientation roll, -90 ~ 90 */
	input_set_abs_params(ecs_data_device, ABS_RZ, 
		-65536/4, 65536/4, 0, 0);
	/* orientation status, 0 ~ 3 */
	input_set_abs_params(ecs_data_device, ABS_RUDDER, 
		0, 100, 0, 0);
	/* proximity sensor */	
	input_set_abs_params(ecs_data_device, ABS_DISTANCE,
		0, 1, 0, 0);

	ecs_data_device->name = ECS_DATA_DEV_NAME;
	res = input_register_device(ecs_data_device);
	if (res) {
		pr_err("%s: unable to register input device: %s\n",
			__FUNCTION__, ecs_data_device->name);
		goto out_free_input;
	}

	res = misc_register(&ecs_ctrl_device);
	if (res) {
		pr_err("%s: ecs_ctrl_device register failed\n", __FUNCTION__);
		goto out_free_input;
	}
	res = device_create_file(ecs_ctrl_device.this_device, &dev_attr_ecs_ctrl);
	if (res) {
		pr_err("%s: device_create_file failed\n", __FUNCTION__);
		goto out_deregister_misc;
	}

	/* set initial proximity value as 1 */
	input_report_abs(ecs_data_device, ABS_DISTANCE, 1);
	input_sync(ecs_data_device);

	printk(KERN_INFO "[MECS] ecompass driver: end\n");
	return 0;

out_deregister_misc:
	misc_deregister(&ecs_ctrl_device);
out_free_input:
	input_free_device(ecs_data_device);
out:
	return res;
}
Exemple #27
0
static int cm36686_i2c_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct cm36686_data *cm36686 = NULL;

	pr_info("%s is called.\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s: i2c functionality check failed!\n", __func__);
		return ret;
	}

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

	cm36686->pdata = client->dev.platform_data;
	cm36686->i2c_client = client;
	i2c_set_clientdata(client, cm36686);
	mutex_init(&cm36686->power_lock);
	mutex_init(&cm36686->read_lock);

	if(cm36686->pdata->cm36686_light_power != NULL) {
		cm36686->cm36686_light_vddpower = cm36686->pdata->cm36686_light_power;
		if (cm36686->cm36686_light_vddpower)
			cm36686->cm36686_light_vddpower(true);
	}

	if(cm36686->pdata->cm36686_proxi_power != NULL) {
		cm36686->cm36686_proxi_vddpower = cm36686->pdata->cm36686_proxi_power;
		if (cm36686->cm36686_proxi_vddpower)
			cm36686->cm36686_proxi_vddpower(true);
	}

	/* wake lock init for proximity sensor */
	wake_lock_init(&cm36686->prx_wake_lock, WAKE_LOCK_SUSPEND,
			"prx_wake_lock");
	if (cm36686->pdata->cm36686_led_on) {
		cm36686->pdata->cm36686_led_on(true);
		msleep(20);
	}
	/* Check if the device is there or not. */
	ret = cm36686_i2c_write_word(cm36686, REG_CS_CONF1, 0x0001);
	if (ret < 0) {
		pr_err("%s: cm36686 is not connected.(%d)\n", __func__, ret);
		goto err_setup_reg;
	}

	/* setup initial registers */
	ret = cm36686_setup_reg(cm36686);
	if (ret < 0) {
		pr_err("%s: could not setup regs\n", __func__);
		goto err_setup_reg;
	}

	if (cm36686->pdata->cm36686_led_on)
		cm36686->pdata->cm36686_led_on(false);

	if (cm36686->cm36686_light_vddpower)
		cm36686->cm36686_light_vddpower(false);

	if (cm36686->cm36686_proxi_vddpower)
		cm36686->cm36686_proxi_vddpower(false);

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

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

	ret = input_register_device(cm36686->proximity_input_dev);
	if (ret < 0) {
		input_free_device(cm36686->proximity_input_dev);
		pr_err("%s: could not register input device\n", __func__);
		goto err_input_register_device_proximity;
	}

	ret = sysfs_create_group(&cm36686->proximity_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;
	}
#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(cm36686->proximity_input_dev);
	if (ret < 0) {
		pr_err("%s - proximity_sensors_initialize_symlink error(%d).\n",
                        __func__, ret);
		goto err_setup_irq;
	}
#endif
	/* setup irq */
	ret = cm36686_setup_irq(cm36686);
	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	/* For factory test mode, we use timer to get average proximity data. */
	/* prox_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm36686->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm36686->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);/*2 sec*/
	cm36686->prox_timer.function = cm36686_prox_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	cm36686->prox_wq = create_singlethread_workqueue("cm36686_prox_wq");
	if (!cm36686->prox_wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create prox workqueue\n", __func__);
		goto err_create_prox_workqueue;
	}
	/* this is the thread function we run on the work queue */
	INIT_WORK(&cm36686->work_prox, cm36686_work_func_prox);

	/* allocate lightsensor input_device */
	cm36686->light_input_dev = input_allocate_device();
	if (!cm36686->light_input_dev) {
		pr_err("%s: could not allocate light input device\n", __func__);
		goto err_input_allocate_device_light;
	}

	input_set_drvdata(cm36686->light_input_dev, cm36686);
	cm36686->light_input_dev->name = "light_sensor";
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_MISC);
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_DIAL);
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_WHEEL);

	ret = input_register_device(cm36686->light_input_dev);
	if (ret < 0) {
		input_free_device(cm36686->light_input_dev);
		pr_err("%s: could not register input device\n", __func__);
		goto err_input_register_device_light;
	}

	ret = sysfs_create_group(&cm36686->light_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;
	}
#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(cm36686->light_input_dev);
	if (ret < 0) {
		pr_err("%s - light_sensors_initialize_symlink error(%d).\n",
                        __func__, ret);
		goto err_create_light_workqueue;
	}
#endif
	/* light_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm36686->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm36686->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
	cm36686->light_timer.function = cm36686_light_timer_func;

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

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

	/* set sysfs for proximity sensor */
	cm36686->proximity_dev = sensors_classdev_register("proximity_sensor");
	if (IS_ERR(cm36686->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_device_create;
	}

	if (device_create_file(cm36686->proximity_dev, &dev_attr_state) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_state.attr.name);
		goto err_proximity_device_create_file1;
	}

	if (device_create_file(cm36686->proximity_dev, &attr_prox_raw) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			attr_prox_raw.attr.name);
		goto err_proximity_device_create_file2;
	}

#ifdef CM36686_CANCELATION
	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_cal) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_cal.attr.name);
		goto err_proximity_device_create_file3;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_offset_pass) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_offset_pass.attr.name);
		goto err_proximity_device_create_file4;
	}
#endif
	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_avg) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_avg.attr.name);
		goto err_proximity_device_create_file5;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_thresh_high) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_thresh_high.attr.name);
		goto err_proximity_device_create_file6;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_vendor) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_vendor.attr.name);
		goto err_proximity_device_create_file7;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_name) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_name.attr.name);
		goto err_proximity_device_create_file8;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_thresh_low) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_thresh_low.attr.name);
		goto err_proximity_device_create_file9;
	}

	dev_set_drvdata(cm36686->proximity_dev, cm36686);

	/* set sysfs for light sensor */
	cm36686->light_dev = sensors_classdev_register("light_sensor");
	if (IS_ERR(cm36686->light_dev)) {
		pr_err("%s: could not create light_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_lux) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_lux.attr.name);
		goto err_light_device_create_file1;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_raw_data) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_raw_data.attr.name);
		goto err_light_device_create_file2;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_vendor) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_vendor.attr.name);
		goto err_light_device_create_file3;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_name) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_name.attr.name);
		goto err_light_device_create_file4;
	}

	dev_set_drvdata(cm36686->light_dev, cm36686);

	pr_info("%s is success.\n", __func__);
	goto done;

/* error, unwind it all */
err_light_device_create_file4:
	device_remove_file(cm36686->light_dev, &dev_attr_vendor);
err_light_device_create_file3:
	device_remove_file(cm36686->light_dev, &dev_attr_raw_data);
err_light_device_create_file2:
	device_remove_file(cm36686->light_dev, &dev_attr_lux);
err_light_device_create_file1:
	sensors_classdev_unregister(cm36686->light_dev);
err_light_device_create:
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_low);
err_proximity_device_create_file9:
	device_remove_file(cm36686->proximity_dev, &dev_attr_name);
err_proximity_device_create_file8:
	device_remove_file(cm36686->proximity_dev, &dev_attr_vendor);
err_proximity_device_create_file7:
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_high);
err_proximity_device_create_file6:
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_avg);
err_proximity_device_create_file5:
#ifdef CM36686_CANCELATION
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_offset_pass);
err_proximity_device_create_file4:
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_cal);
err_proximity_device_create_file3:
#endif
	device_remove_file(cm36686->proximity_dev, &attr_prox_raw);
err_proximity_device_create_file2:
	device_remove_file(cm36686->proximity_dev, &dev_attr_state);
err_proximity_device_create_file1:
	sensors_classdev_unregister(cm36686->proximity_dev);
err_proximity_device_create:
	destroy_workqueue(cm36686->light_wq);
err_create_light_workqueue:
	sysfs_remove_group(&cm36686->light_input_dev->dev.kobj,
			   &light_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(cm36686->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(cm36686->prox_wq);
err_create_prox_workqueue:
	free_irq(cm36686->irq, cm36686);
	gpio_free(cm36686->pdata->irq);
err_setup_irq:
	sysfs_remove_group(&cm36686->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(cm36686->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
err_setup_reg:
	if (cm36686->pdata->cm36686_led_on)
		cm36686->pdata->cm36686_led_on(false);

	if (cm36686->cm36686_light_vddpower)
		cm36686->cm36686_light_vddpower(false);

	if (cm36686->cm36686_proxi_vddpower)
		cm36686->cm36686_proxi_vddpower(false);

	wake_lock_destroy(&cm36686->prx_wake_lock);
	mutex_destroy(&cm36686->read_lock);
	mutex_destroy(&cm36686->power_lock);
	kfree(cm36686);
done:
	return ret;
}
Exemple #28
0
static int navpoint_probe(struct platform_device *pdev)
{
	const struct navpoint_platform_data *pdata =
					dev_get_platdata(&pdev->dev);
	struct ssp_device *ssp;
	struct input_dev *input;
	struct navpoint *navpoint;
	int error;

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

	if (gpio_is_valid(pdata->gpio)) {
		error = gpio_request_one(pdata->gpio, GPIOF_OUT_INIT_LOW,
					 "SYNAPTICS_ON");
		if (error)
			return error;
	}

	ssp = pxa_ssp_request(pdata->port, pdev->name);
	if (!ssp) {
		error = -ENODEV;
		goto err_free_gpio;
	}

	/* HaRET does not disable devices before jumping into Linux */
	if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
		pxa_ssp_write_reg(ssp, SSCR0, 0);
		dev_warn(&pdev->dev, "ssp%d already enabled\n", pdata->port);
	}

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

	navpoint->ssp = ssp;
	navpoint->input = input;
	navpoint->dev = &pdev->dev;
	navpoint->gpio = pdata->gpio;

	input->name = pdev->name;
	input->dev.parent = &pdev->dev;

	__set_bit(EV_KEY, input->evbit);
	__set_bit(EV_ABS, input->evbit);
	__set_bit(BTN_LEFT, input->keybit);
	__set_bit(BTN_TOUCH, input->keybit);
	__set_bit(BTN_TOOL_FINGER, input->keybit);

	input_set_abs_params(input, ABS_X,
			     NAVPOINT_X_MIN, NAVPOINT_X_MAX, 0, 0);
	input_set_abs_params(input, ABS_Y,
			     NAVPOINT_Y_MIN, NAVPOINT_Y_MAX, 0, 0);
	input_set_abs_params(input, ABS_PRESSURE,
			     NAVPOINT_PRESSURE_MIN, NAVPOINT_PRESSURE_MAX,
			     0, 0);

	input->open = navpoint_open;
	input->close = navpoint_close;

	input_set_drvdata(input, navpoint);

	error = request_irq(ssp->irq, navpoint_irq, 0, pdev->name, navpoint);
	if (error)
		goto err_free_mem;

	error = input_register_device(input);
	if (error)
		goto err_free_irq;

	platform_set_drvdata(pdev, navpoint);
	dev_dbg(&pdev->dev, "ssp%d, irq %d\n", pdata->port, ssp->irq);

	return 0;

err_free_irq:
	free_irq(ssp->irq, navpoint);
err_free_mem:
	input_free_device(input);
	kfree(navpoint);
	pxa_ssp_free(ssp);
err_free_gpio:
	if (gpio_is_valid(pdata->gpio))
		gpio_free(pdata->gpio);

	return error;
}
Exemple #29
0
static int aps_12d_probe(
	struct i2c_client *client, const struct i2c_device_id *id)
{	
	int ret;
	struct aps_data *aps;
	int i;

	printk(KERN_INFO "aps_12d_probe enter\n ");
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		printk(KERN_ERR "aps_12d_probe: need I2C_FUNC_I2C\n");
		ret = -ENODEV;
		goto err_check_functionality_failed;
	}

	if(machine_is_msm7x25_u8150() || machine_is_msm7x25_c8150())
	{
		if((get_hw_sub_board_id() == HW_VER_SUB_VA) || ((get_hw_sub_board_id() == HW_VER_SUB_VB)))
		{
			printk(KERN_ERR "aps_12d_probe: aps is not supported in c8150 and u8150 T1 board!\n");
			ret = -ENODEV;
			goto err_check_functionality_failed; 
		}
	}
	
	aps = kzalloc(sizeof(*aps), GFP_KERNEL);
	if (aps == NULL) {
		ret = -ENOMEM;
		goto err_alloc_data_failed;
	}

	mutex_init(&aps->mlock);

	INIT_WORK(&aps->work, aps_12d_work_func);
	aps->client = client;
	i2c_set_clientdata(client, aps);

	printk(KERN_INFO "aps_12d_probe send command 2\n ");
	/* Command 2 register: 25mA,DC,12bit,Range1 */
	ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \
	                         (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \
	                                   APS_12D_FREQ_SEL_DC << 4 | \
	                                   APS_12D_RES_SEL_12 << 2 | \
	                                   APS_12D_RANGE_SEL_ALS_1000));
	if (ret < 0) {
		goto err_detect_failed;
	}

	if( machine_is_msm7x25_u8150() || machine_is_msm7x25_c8150() || machine_is_msm7x25_u8159()\
		|| machine_is_msm7x25_u8160() || machine_is_msm7x25_u8130() || machine_is_msm7x25_c8510())
	{
		range_index = 0;
		high_threshold = high_threshold_value[range_index];
		low_threshold = low_threshold_value[range_index];


		for(i = 0; i < TOTAL_RANGE_NUM; i++)
		{
			/* NOTE: do NOT use the last one */
			up_range_value[i] = MAX_ADC_OUTPUT - high_threshold_value[i] - UP_RANGE_FIX;
#ifdef DEBUG_AUTO_RANGE_ADJUST
			printk("up_range_value[%d] = %d.\n",i, up_range_value[i]);
#endif
		}

		down_range_value[0] = 0;
		for(i = 1; i < TOTAL_RANGE_NUM; i++)
		{
			/* NOTE: do not use the first one */
			down_range_value[i] = (MAX_ADC_OUTPUT - high_threshold_value[i-1] - (MAX_ADC_OUTPUT / ADJUST_GATE)) / 4;
#ifdef DEBUG_AUTO_RANGE_ADJUST
			printk("down_range_value[%d] = %d\n",i, down_range_value[i]);
#endif
		}

	}
	else if( machine_is_msm7x25_u8500() || machine_is_msm7x25_um840())
	{
		high_threshold = 300;
		low_threshold = 280;
	}
	else if( machine_is_msm7x25_u8300() )
	{
/* set shutter value for u8300 */
		high_threshold = 710;
		low_threshold = 650;
	}
	else
	{
		high_threshold = 780;
		low_threshold = 730;
	}
	
	if (sensor_dev == NULL) {
		aps->input_dev = input_allocate_device();
		if (aps->input_dev == NULL) {
			ret = -ENOMEM;
			printk(KERN_ERR "aps_12d_probe: Failed to allocate input device\n");
			goto err_input_dev_alloc_failed;
		}
		aps->input_dev->name = "sensors";
		
		aps->input_dev->id.bustype = BUS_I2C;
		
		input_set_drvdata(aps->input_dev, aps);
		
		ret = input_register_device(aps->input_dev);
		if (ret) {
			printk(KERN_ERR "aps_probe: Unable to register %s input device\n", aps->input_dev->name);
			goto err_input_register_device_failed;
		}
		sensor_dev = aps->input_dev;
	} else {
		aps->input_dev = sensor_dev;
	}

	set_bit(EV_ABS, aps->input_dev->evbit);
	input_set_abs_params(aps->input_dev, ABS_LIGHT, 0, 10240, 0, 0);
	input_set_abs_params(aps->input_dev, ABS_DISTANCE, 0, 1, 0, 0);

	ret = misc_register(&light_device);
	if (ret) {
		printk(KERN_ERR "aps_12d_probe: light_device register failed\n");
		goto err_light_misc_device_register_failed;
	}

	ret = misc_register(&proximity_device);
	if (ret) {
		printk(KERN_ERR "aps_12d_probe: proximity_device register failed\n");
		goto err_proximity_misc_device_register_failed;
	}

	if( light_device.minor != MISC_DYNAMIC_MINOR ){
		light_device_minor = light_device.minor;
	}
	
	if( proximity_device.minor != MISC_DYNAMIC_MINOR ){
		proximity_device_minor = proximity_device.minor ;
	}

	wake_lock_init(&proximity_wake_lock, WAKE_LOCK_SUSPEND, "proximity");

	hrtimer_init(&aps->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	aps->timer.function = aps_timer_func;
	
	aps_wq = create_singlethread_workqueue("aps_wq");

	if (!aps_wq) {
		ret = -ENOMEM;
		goto err_create_workqueue_failed;
	}
	
	this_aps_data =aps;

#ifdef CONFIG_HAS_EARLYSUSPEND
	aps->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	aps->early_suspend.suspend = aps_12d_early_suspend;
	aps->early_suspend.resume = aps_12d_early_resume;
	register_early_suspend(&aps->early_suspend);
#endif

	#ifdef CONFIG_HUAWEI_HW_DEV_DCT
	/* detect current device successful, set the flag as present */
	set_hw_dev_flag(DEV_I2C_APS);
	#endif

	printk(KERN_INFO "aps_12d_probe: Start Proximity Sensor APS-12D\n");

#ifdef CONFIG_MELFAS_UPDATE_TS_FIRMWARE
	TS_updateFW_aps_data = this_aps_data;
	TS_updateFW_aps_wq = aps_wq;
#endif

	return 0;
	
err_create_workqueue_failed:
	misc_deregister(&proximity_device);
err_proximity_misc_device_register_failed:
	misc_deregister(&light_device);
err_light_misc_device_register_failed:
err_input_register_device_failed:
	input_free_device(aps->input_dev);
err_input_dev_alloc_failed:
err_detect_failed:
	kfree(aps);
err_alloc_data_failed:
err_check_functionality_failed:
	return ret;
  
}
Exemple #30
0
static int ecs_ctrl_ioctl(struct inode *inode, struct file *file, 
	unsigned int cmd, unsigned long arg)
{
	void __user *pa = (void __user *)arg;
	short flag;
	short delay;
	int parms[4];
	int ypr[12];

	switch (cmd) {
	case ECOMPASS_IOC_SET_MODE:
		break;
	case ECOMPASS_IOC_SET_DELAY:
		if (copy_from_user(&delay, pa, sizeof(delay)))
			return -EFAULT;
		ecompass_delay = delay;
		break;
	case ECOMPASS_IOC_GET_DELAY:
		delay = ecompass_delay;
		if (copy_to_user(pa, &delay, sizeof(delay)))
			return -EFAULT;
		break;

	case ECOMPASS_IOC_SET_AFLAG:
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&a_flag, flag);
		break;
	case ECOMPASS_IOC_GET_AFLAG:
		flag = atomic_read(&a_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;
	case ECOMPASS_IOC_SET_MFLAG:
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&m_flag, flag);
		break;
	case ECOMPASS_IOC_GET_MFLAG:
		flag = atomic_read(&m_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;
	case ECOMPASS_IOC_SET_OFLAG:
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&o_flag, flag);
		break;
	case ECOMPASS_IOC_GET_OFLAG:
		flag = atomic_read(&o_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;

	case ECOMPASS_IOC_SET_APARMS:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* acceleration x-axis */
		input_set_abs_params(ecs_data_device, ABS_X, 
			parms[0], parms[1], parms[2], parms[3]);
		/* acceleration y-axis */
		input_set_abs_params(ecs_data_device, ABS_Y, 
			parms[0], parms[1], parms[2], parms[3]);
		/* acceleration z-axis */
		input_set_abs_params(ecs_data_device, ABS_Z, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_APARMS:
		break;
	case ECOMPASS_IOC_SET_MPARMS:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* magnetic raw x-axis */
		input_set_abs_params(ecs_data_device, ABS_HAT0X, 
			parms[0], parms[1], parms[2], parms[3]);
		/* magnetic raw y-axis */
		input_set_abs_params(ecs_data_device, ABS_HAT0Y, 
			parms[0], parms[1], parms[2], parms[3]);
		/* magnetic raw z-axis */
		input_set_abs_params(ecs_data_device, ABS_BRAKE, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_MPARMS:
		break;
	case ECOMPASS_IOC_SET_OPARMS_YAW:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* orientation yaw */
		input_set_abs_params(ecs_data_device, ABS_RX, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_OPARMS_YAW:
		break;
	case ECOMPASS_IOC_SET_OPARMS_PITCH:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* orientation pitch */
		input_set_abs_params(ecs_data_device, ABS_RY, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_OPARMS_PITCH:
		break;
	case ECOMPASS_IOC_SET_OPARMS_ROLL:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* orientation roll */
		input_set_abs_params(ecs_data_device, ABS_RZ, 
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_OPARMS_ROLL:
		break;

	case ECOMPASS_IOC_SET_YPR:
		if (copy_from_user(ypr, pa, sizeof(ypr)))
			return -EFAULT;
		/* Report acceleration sensor information */
		if (atomic_read(&a_flag)) {
			input_report_abs(ecs_data_device, ABS_X, ypr[0]);
			input_report_abs(ecs_data_device, ABS_Y, ypr[1]);
			input_report_abs(ecs_data_device, ABS_Z, ypr[2]);
			input_report_abs(ecs_data_device, ABS_WHEEL, ypr[3]);
		}

		/* Report magnetic sensor information */
		if (atomic_read(&m_flag)) {
			input_report_abs(ecs_data_device, ABS_HAT0X, ypr[4]);
			input_report_abs(ecs_data_device, ABS_HAT0Y, ypr[5]);
			input_report_abs(ecs_data_device, ABS_BRAKE, ypr[6]);
			input_report_abs(ecs_data_device, ABS_GAS, ypr[7]);
		}

		/* Report orientation information */
		if (atomic_read(&o_flag)) {
			input_report_abs(ecs_data_device, ABS_RX, ypr[8]);
			input_report_abs(ecs_data_device, ABS_RY, ypr[9]);
			input_report_abs(ecs_data_device, ABS_RZ, ypr[10]);
			input_report_abs(ecs_data_device, ABS_RUDDER, ypr[11]);
		}

		input_sync(ecs_data_device);
		break;

	default:
		break;
	}

	return 0;
}