Exemplo n.º 1
0
void cma3000_init()
{
	uint8_t cntrl_reg;

	cma3000_reset();
	cntrl_reg = ((CMA3000_8G_MODE << CMA3000_G_RANGE) | (HIGH << CMA3000_IRQ_POLARITY) | (CMA3000_MDEXIT_MD << CMA3000_MDET_EXIT)
			| (DISABLE << CMA3000_I2C_DIS) | (1 << BIT3) | (0 << BIT2) | (0 << BIT1) | (ENABLE << CMA3000_IRQ_DIS));
	uint8_t ucMD_Threshold = 0x10;				//	Set Threshold to 1G
	//	Write Control and threshold registers
	cma_as_write_register(CMA3000_CTRL_REG, cntrl_reg);
	cma_as_write_register(CMA3000_MDTHR_REG, ucMD_Threshold);
}
struct cma3000_accl_data *cma3000_init(struct device *dev, int irq,
				       const struct cma3000_bus_ops *bops)
{
	const struct cma3000_platform_data *pdata = dev->platform_data;
	struct cma3000_accl_data *data;
	struct input_dev *input_dev;
	int rev;
	int error;

	if (!pdata) {
		dev_err(dev, "platform data not found\n");
		error = -EINVAL;
		goto err_out;
	}


	/* if no IRQ return error */
	if (irq == 0) {
		error = -EINVAL;
		goto err_out;
	}

	data = kzalloc(sizeof(struct cma3000_accl_data), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!data || !input_dev) {
		error = -ENOMEM;
		goto err_free_mem;
	}

	data->dev = dev;
	data->input_dev = input_dev;
	data->bus_ops = bops;
	data->pdata = pdata;
	data->irq = irq;
	mutex_init(&data->mutex);

	data->mode = pdata->mode;
	if (data->mode < CMAMODE_DEFAULT || data->mode > CMAMODE_POFF) {
		data->mode = CMAMODE_MOTDET;
		dev_warn(dev,
			 "Invalid mode specified, assuming Motion Detect\n");
	}

	data->g_range = pdata->g_range;
	if (data->g_range != CMARANGE_2G && data->g_range != CMARANGE_8G) {
		dev_info(dev,
			 "Invalid G range specified, assuming 8G\n");
		data->g_range = CMARANGE_8G;
	}

	input_dev->name = "cma3000-accelerometer";
	input_dev->id.bustype = bops->bustype;
	input_dev->open = cma3000_open;
	input_dev->close = cma3000_close;

	 __set_bit(EV_ABS, input_dev->evbit);

	input_set_abs_params(input_dev, ABS_X,
			-data->g_range, data->g_range, pdata->fuzz_x, 0);
	input_set_abs_params(input_dev, ABS_Y,
			-data->g_range, data->g_range, pdata->fuzz_y, 0);
	input_set_abs_params(input_dev, ABS_Z,
			-data->g_range, data->g_range, pdata->fuzz_z, 0);
	input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);

	input_set_drvdata(input_dev, data);

	error = cma3000_reset(data);
	if (error)
		goto err_free_mem;

	rev = CMA3000_READ(data, CMA3000_REVID, "Revid");
	if (rev < 0) {
		error = rev;
		goto err_free_mem;
	}

	pr_info("CMA3000 Accelerometer: Revision %x\n", rev);

	error = request_threaded_irq(irq, NULL, cma3000_thread_irq,
				     pdata->irqflags | IRQF_ONESHOT,
				     "cma3000_d0x", data);
	if (error) {
		dev_err(dev, "request_threaded_irq failed\n");
		goto err_free_mem;
	}

	error = input_register_device(data->input_dev);
	if (error) {
		dev_err(dev, "Unable to register input device\n");
		goto err_free_irq;
	}

	return data;

err_free_irq:
	free_irq(irq, data);
err_free_mem:
	input_free_device(input_dev);
	kfree(data);
err_out:
	return ERR_PTR(error);
}
int cma3000_init(struct cma3000_accl_data *data)
{
	int ret = 0, fuzz_x, fuzz_y, fuzz_z, g_range;
	uint32_t irqflags;
	uint8_t ctrl;

	INIT_DELAYED_WORK(&data->input_work, cma3000_input_work_func);

	if (data->client->dev.platform_data == NULL) {
		dev_err(&data->client->dev, "platform data not found\n");
		goto err_op2_failed;
	}

	memcpy(&(data->pdata), data->client->dev.platform_data,
		sizeof(struct cma3000_platform_data));

	ret = cma3000_reset(data);
	if (ret)
		goto err_op2_failed;

	ret = cma3000_read(data, CMA3000_REVID, "Revid");
	if (ret < 0)
		goto err_op2_failed;

	pr_info("CMA3000 Acclerometer : Revision %x\n", ret);

	/* Bring it out of default power down state */
	ret = cma3000_poweron(data);
	if (ret < 0)
		goto err_op2_failed;

	data->req_poll_rate = data->pdata.def_poll_rate;
	fuzz_x = data->pdata.fuzz_x;
	fuzz_y = data->pdata.fuzz_y;
	fuzz_z = data->pdata.fuzz_z;
	g_range = data->pdata.g_range;
	irqflags = data->pdata.irqflags;

	data->input_dev = input_allocate_device();
	if (data->input_dev == NULL) {
		ret = -ENOMEM;
		dev_err(&data->client->dev,
			"Failed to allocate input device\n");
		goto err_op2_failed;
	}

	data->input_dev->name = "cma3000-acclerometer";

#ifdef CONFIG_INPUT_CMA3000_I2C
	data->input_dev->id.bustype = BUS_I2C;
#endif

	 __set_bit(EV_ABS, data->input_dev->evbit);
	 __set_bit(EV_MSC, data->input_dev->evbit);

	input_set_abs_params(data->input_dev, ABS_X, -g_range,
				g_range, fuzz_x, 0);
	input_set_abs_params(data->input_dev, ABS_Y, -g_range,
				g_range, fuzz_y, 0);
	input_set_abs_params(data->input_dev, ABS_Z, -g_range,
				g_range, fuzz_z, 0);
	input_set_abs_params(data->input_dev, ABS_MISC, 0,
				1, 0, 0);

	ret = input_register_device(data->input_dev);
	if (ret) {
		dev_err(&data->client->dev,
			"Unable to register input device\n");
		goto err_op2_failed;
	}

	mutex_init(&data->mutex);

	if (data->client->irq) {
		ret = request_irq(data->client->irq, cma3000_isr,
					irqflags | IRQF_ONESHOT,
					data->client->name, data);

		if (ret < 0) {
			dev_err(&data->client->dev,
				"request_threaded_irq failed\n");
			goto err_op1_failed;
		}
	} else {
		/*There is no IRQ set, disable IRQ on CMA*/
		ctrl = cma3000_read(data, CMA3000_CTRL, "Status");
		ctrl |= 0x1;
		cma3000_set(data, CMA3000_CTRL, ctrl, "Disable IRQ");
	}

	ret = sysfs_create_group(&data->client->dev.kobj, &cma3000_attr_group);
	if (ret) {
		dev_err(&data->client->dev,
			"failed to create sysfs entries\n");
		goto err_op1_failed;
	}

	cma3000_set_mode(data, CMAMODE_POFF);

	return 0;

err_op1_failed:
	mutex_destroy(&data->mutex);
	input_unregister_device(data->input_dev);
err_op2_failed:
	if (data != NULL) {
		if (data->input_dev != NULL)
			input_free_device(data->input_dev);
	}

	return ret;
}